home *** CD-ROM | disk | FTP | other *** search
/ Sound Fx / Sound Fx.iso / Software / UNZIPED / SBPLY254 / SOURCE.ZIP / PLAY.C < prev    next >
C/C++ Source or Header  |  1996-09-01  |  73KB  |  3,033 lines

  1. /***************************************************************************/
  2. /* Play.c  -- Routines to read and playback sound files                    */
  3. /* Copyright (c) 1995 John A. Ball                                         */
  4. /*                                                                         */
  5. /* This source is available for your own personal use only! You may make   */
  6. /* any changes you wish but please do not distribute modified source code. */
  7. /* Please notify me of any errors or improvements.                         */
  8. /*                                                                         */
  9. /* by John A. Ball   September 1, 1996                                     */
  10. /***************************************************************************/
  11.  
  12. #define BUFFSIZE 16*1024
  13. #define BIGBUFFER 63*1024
  14. #define getrandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
  15. #define TRUE 1
  16. #define NOCOMPRESS 100
  17.  
  18. #include <conio.h>
  19. #include <stdio.h>
  20. #include <dos.h>
  21. #include <errno.h>
  22. #include <stdlib.h>
  23. #include <fcntl.h>
  24. #include <sys\types.h>
  25. #include <sys\stat.h>
  26. #include <io.h>
  27. #include <malloc.h>
  28. #include <math.h>
  29. #include <string.h>
  30. #include <sound.h>
  31. #include <graph.h>
  32. #include <ems.h>
  33.  
  34.     long fileinfo(struct find_t *find);
  35.  
  36.  
  37.     struct names
  38.     {
  39.     char name[13];
  40.     };
  41.  
  42.     struct CARD_INFO card_info;
  43.     int verbose=1;
  44.     int rip=0;
  45.     int ctwav=0;                    /* Create WAV file flag */
  46.     int ctvoc=0;                    /* Create VOC file flag */
  47.     int ctsam=0;                    /* Create SAM file flag */
  48.     int ctsnd=0;                    /* Create SND file flag */
  49.     int file_info=0;
  50.     char *buffer;
  51.     int volume=MIDVOLUME;
  52.     int compression=0;
  53.     int magnitude=0;
  54.     int default_bits=8;
  55.     int halve_buffer=0;
  56.     int stop=0;
  57.     int debug=0;
  58.     int repeat=1;
  59.     int num_repeats=0;
  60.     int error=0;
  61.     int multi_error=0;
  62.     int random=0;
  63.     int emm_present=0;
  64.     int emm_version=0;
  65.     int emm_status=0;
  66.     int emm_pages=0;
  67.     int emm_pages_free=0;
  68.     char _far *emm_page[4];
  69.     int emm_pages_req=0;
  70.     unsigned p=0;
  71.     int pp=0;
  72.     int emm_win_size=1;
  73.     int emm_error=0;
  74.     int conversion_table=1;
  75.     unsigned int play_rate=11000;
  76.     unsigned int pitch=1;
  77.     char _far **fbuffer;
  78.     char *workbuf;
  79.     unsigned int dma_size=0;
  80.     unsigned long mem_total=600000;
  81.     char source_file_name[80];
  82.     char msg[]="Error! ";
  83.     union REGS inregs, outregs;
  84.     struct SREGS segregs;
  85.     long fileinfo(struct find_t *find);
  86.     long append=0;
  87.     char a_file_name[13];
  88.     int shell=0;
  89.     struct SOUND info;
  90.  
  91. char *get_file_name(int argc, char *argv[]);
  92. void help(void);
  93. int play_sound(char *file_name);
  94. char get_file_type(char *file_name);
  95. int read_tandy(struct SOUND *hp, int source_handle);
  96. int read_voc(struct SOUND *hp, int source_handle);
  97. int read_wav(struct SOUND *hp, int source_handle);
  98. int read_iff(struct SOUND *hp, int source_handle);
  99. int read_sam(struct SOUND *hp, int source_handle);
  100. int read_mod(struct SOUND *hp, int source_handle);
  101. int read_steve(struct SOUND *hp, int source_handle);
  102. int read_unknown(struct SOUND *hp, int source_handle);
  103. int read_mac(struct SOUND *hp, int source_handle);
  104. int read_au(struct SOUND *hp, int source_handle);
  105. int play_block(struct SOUND *hp, int source_handle);
  106. int print_file_info(struct SOUND *hp);
  107. int create_sam(long number_of_samples, int source_handle);
  108. int create_wav(long number_of_samples, unsigned int block_size, unsigned int frequency);
  109. int create_voc(long number_of_samples, unsigned int block_size, unsigned int frequency);
  110. int create_snd(long number_of_samples, unsigned int block_size, unsigned int frequency);
  111. int create_raw(long number_of_samples, unsigned int block_size, unsigned int frequency);
  112. unsigned get_dma_size(void);
  113. unsigned long get_mem_size(void);
  114. long mm(long l);
  115. unsigned int mmi(unsigned int i);
  116. void mmf(double long *i);
  117. void to_unsigned(char _far *hp,unsigned int k);
  118. void to_signed(char _far *hp,unsigned int k);
  119. void to_8bit(char _far *hp,unsigned int k,int byte_format);
  120. void down_sample(char _far *hp,unsigned int k);
  121. unsigned int change_frequency(char _far *hp,unsigned int k,unsigned int freq,unsigned int nfreq);
  122. int m_gain(unsigned char _far *hp, unsigned int k);
  123. int p_gain(unsigned char _far *hp, unsigned int k);
  124. void get_speed(char *pdest);
  125. void get_volume(char *pdest);
  126. void get_num_repeats(char *pdest);
  127. int get_card_type(void);
  128. int uncompress_ulaw(char _far *hp, unsigned int number_samples);
  129. int uncompress_alaw(char _far *hp, unsigned int number_samples);
  130. int snd_shell(void);
  131. void display_menu(void);
  132. int showfiles(char *fnp,int num);
  133. char *get_files(char *fnp);
  134. int find_files(void);
  135. int show_cursor(char *fnp, int cp);
  136. int show_page(char *fnp,int num);
  137. int play_it(char *fnp);
  138. int get_names(char *rnp, char *file_name);
  139. int binexp(int i);
  140. void p_cerror(char *msg, char *name);
  141. int check_esc(void);
  142.  
  143. int main(int argc, char *argv[])
  144. {
  145.     struct find_t find;
  146.     char file_path[80];
  147.     char file_name[13];
  148.     char file[93];
  149.     char dot_star[]=".*";
  150.     char *name;
  151.     char *path;
  152.     char *pfile;
  153.     char *rnp;
  154.     char *rn;
  155.     int sh='\\';
  156.     int colon=':';
  157.     int dot='.';
  158.     int found;
  159.     int length=0;
  160.     int i=0,k=0;
  161.     int key;
  162.     int num_files=0;
  163.  
  164.     name=get_file_name(argc, argv);
  165.     if(name != NULL){
  166.       path=strrchr(name,sh);
  167.       if(path==NULL)path=strrchr(name,colon);
  168.       length=(int)(path-name);
  169.       if(length > 80)length=80;
  170.       for(i=0;i<length+1;i++)
  171.        {
  172.        file_path[i]=source_file_name[i];
  173.        }
  174.       file_path[i]='\0';
  175.       pfile=strcpy(file,file_path);
  176.       pfile=strcpy(file_name,&source_file_name[i]);
  177.       name=strrchr(file_name,dot);
  178.       if(name==NULL)strcat(source_file_name,dot_star);
  179.       found=_dos_findfirst(source_file_name,_A_NORMAL,&find);
  180.       if(!found){
  181.        name=&find.name[0];
  182.        length=strlen(name);
  183.        if(length > 12)length=12;
  184.        k=0;
  185.        for(i=0;i<length+1;i++)
  186.         {
  187.         file_name[i]=find.name[i];
  188.         }
  189.        file_name[i]='\0';
  190.        k++;
  191.        if(!random){
  192.         pfile=strcat(file,file_name);
  193.         play_sound(file);
  194.         }
  195.        while(!_dos_findnext(&find))
  196.        {
  197.        if(stop)exit(1);
  198.        name=&find.name[0];
  199.        length=strlen(name);
  200.        if(length > 12)length=12;
  201.        for(i=0;i<length+1;i++)
  202.         {
  203.         file_name[i]=find.name[i];
  204.         }
  205.        file_name[i]='\0';
  206.        k++;
  207.        if(!random){
  208.         pfile=strcpy(file,file_path);
  209.         pfile=strcat(file,file_name);
  210.         play_sound(file);
  211.         }
  212.        }
  213.        num_files=k;
  214.        if(random){
  215.         rnp=(char *)malloc(14*num_files);
  216.         if(rnp){
  217.            rn=rnp;
  218.            get_names(rn, source_file_name);
  219.            srand((unsigned)time( NULL ));
  220.            k=getrandom(0,num_files-1);
  221.            rn+=(k*14);
  222.            pfile=strcpy(file,file_path);
  223.            pfile=strcat(file,rn);
  224.            play_sound(file);
  225.            free(rnp);
  226.            }
  227.         else{
  228.           printf("Failure to allocate memory for file names!\n");
  229.           multi_error=1;
  230.         }
  231.        }
  232.        }
  233.        if(found){
  234.          printf("File %s not found!\n",source_file_name);
  235.          multi_error=1;
  236.        }
  237.       }
  238.     else
  239.     return(99);
  240. }
  241. /* Get Sound file name or give program information if error*/
  242.  
  243. char *get_file_name(int argc, char *argv[])
  244.  
  245. {
  246.     char *pdest;
  247.     char options[80];
  248.     int i=0;
  249.  
  250.  
  251.     if(argc == 1){
  252.        verbose=0;
  253.        shell=1;
  254.        snd_shell();
  255.        return(NULL);
  256.     }
  257.  
  258.     strcpy(source_file_name, argv[1]);
  259.     strupr(source_file_name);
  260.     if(argc > 2){
  261.        i=2;
  262.        do{
  263.        strcpy(options, argv[i]);
  264.        strupr(options);
  265.        if(strstr(options,"S"))verbose=0;
  266.        if(strstr(options,"!"))magnitude=1;
  267.        if(strstr(options,"&"))magnitude=-1;
  268.        if(strstr(options,"#"))default_bits=-8;
  269.        if(strstr(options,"X"))debug=1;
  270.        if(strstr(options,"RIP"))ctsam=rip=1;
  271.        if(strstr(options,"C1"))ctwav=1;
  272.        if(strstr(options,"C2"))ctvoc=1;
  273.        if(strstr(options,"C3"))ctsnd=1;
  274.        if(strstr(options,"RAN"))random=1;
  275.        if(pdest=strstr(options,"R:"))get_speed(pdest);
  276.        if(pdest=strstr(options,"V:"))get_volume(pdest);
  277.        if(pdest=strstr(options,"L:"))get_num_repeats(pdest);
  278.        i++;
  279.        }
  280.        while(i < argc);
  281.  
  282.        return(source_file_name);
  283.        }
  284.     if(strstr(source_file_name,"/?")){
  285.        help();
  286.        return (NULL);
  287.        }
  288.  
  289.     return(source_file_name);
  290. }
  291.  
  292. /* Print out Program information */
  293.  
  294. void help(void)
  295. {
  296.     printf("\n" PROGRAM PURPOSE"\n");
  297.     printf("\nPlays VOC, WAV, SND, IFF, AIF, SAM & MOD sound files on ");
  298.     printf(CARD "\n");
  299.     printf("\n"PROGRAM" [drive:][path] [filename] [/S][/!][/&][/#][/X][/Cn][/RIP][/RAN]\n");
  300.     printf(" [R:xxxxx] [V:xxx] [L:xxxxx] \n");
  301.     printf("\n/S Suppress File Information \n");
  302.     printf("/! Amplify \n");
  303.     printf("/& Silence \n");
  304.     printf("/# Data is 8 Bit Signed\n");
  305.     printf("/X Show Debugging Information\n");
  306.     printf("/C1 Create WAV /C2 VOC /C3 SND file\n");
  307.     printf("/RIP Create .SAM files from/for MOD files\n");
  308.     printf("/RAN Select file at random to play\n");
  309.     printf("R:xxxxx Set Default Playback Rate\n");
  310.     printf("V:xxx Set Default Volume (%i - %i)\n",MINVOLUME,MAXVOLUME);
  311.     printf("L:xxxxx Set number of repeat loops 1-32,000\n");
  312.     printf("\n" VERSION "\n");
  313.     printf("\n" COPYRIGHT "\n");
  314. }
  315.  
  316. /* Play sound file on PC speaker */
  317.  
  318. int play_sound(char *file_name)
  319. {
  320.     char type;
  321.     char name[80];
  322.     char *pdest;
  323.     int source_handle;
  324.     int number_read;
  325.     unsigned long file_length;
  326.     unsigned long i;
  327.     int j;
  328.     int k;
  329.     unsigned long l;
  330.  
  331.     if(shell && file_info){
  332.      _settextposition(23,1);
  333.      _settextcolor(14);
  334.      _setbkcolor(9);
  335.       for(i=0;i<6;i++){
  336.         _outtext("                                       ");
  337.       }
  338.     _settextposition(23,1);
  339.     }
  340.  
  341. /* Check for EMS memory */
  342.  
  343.     if(emm_present=EMM_find_manager()){
  344.       emm_version=EMM_get_version();
  345.       emm_status=EMM_get_status();
  346.       emm_page[0]=EMM_get_page_frame();
  347.       emm_pages=EMM_get_pages();
  348.       emm_pages_free=EMM_get_pages_free();
  349.     }
  350.     
  351.     if(debug && emm_present){
  352.        printf("EMS version %01d.%01d found\n",
  353.          emm_version >> 4, emm_version & 0x0f);
  354.        if(emm_status)printf("EMS management status error %Xh\n",
  355.          emm_status);
  356.        printf("%i EMS Pages at Page Frame %Fp with %i pages free\n",
  357.          emm_pages,emm_page[0],emm_pages_free);
  358.     }
  359.  
  360. /* Find Sound Card Available */
  361.  
  362.     card_info.type=PCSPEAKER;
  363.     card_info.type=get_card_type();
  364.  
  365. /* Initalize default values */
  366.  
  367.     info.length=0;
  368.     info.number_samples=0;
  369.     info.frequency=0;
  370.     info.bits=8;
  371.     info.channels=1;
  372.     info.compression=0;             /* Type of hardware compression */
  373.  
  374.     error=0;
  375.     multi_error=0;
  376.     compression=0;
  377.     stop=0;
  378.     repeat=1;
  379.     halve_buffer=0;
  380.     card_info.mode=BIT8_M;          /* Compression capabilities of card */
  381.     conversion_table=1;
  382.  
  383.     repeat=repeat+num_repeats;
  384.  
  385.     strcpy(name,file_name);
  386.     if(verbose)printf("\nSound File %s Information\n",name);
  387.  
  388.     /* Find out total memory available */
  389.  
  390.     mem_total=get_mem_size();
  391.  
  392.     /* Find out size of DMA buffer in protected mode */
  393.  
  394.     if(dma_size == 0){
  395.      dma_size=64000;
  396.      k=get_dma_size();
  397.      if(k < 64 && k > 0)dma_size=k*1024;
  398.      else dma_size=64000;
  399.      if(debug)printf("The DMA buffer size is %u and available memory is %lu bytes\n"
  400.         ,dma_size,mem_total);
  401.     }
  402.  
  403.     /* Allocate memory for work buffer */
  404.  
  405.     if((workbuf =(char *)malloc(BIGBUFFER)) == NULL){
  406.       printf("Failed to allocate memory for work buffer!\n");
  407.       multi_error=1;
  408.       exit(100);
  409.     }
  410.  
  411.     /* Allocate memory for buffer pointers */
  412.  
  413.     k=((mem_total/dma_size) +1);
  414.     if(k < 50)k=50;
  415.     if((fbuffer=(char _far **)malloc((size_t)sizeof(char _far *) * k)) == NULL){
  416.       printf("Failed to allocate memory for buffer pointers!\n");
  417.       multi_error=1;
  418.       exit(100);
  419.     }
  420.  
  421.     /* Allocate memory for file header buffer*/
  422.  
  423.     if((buffer =(char *)malloc(BUFFSIZE)) == NULL){
  424.        perror(msg);
  425.        printf("Failed to allocate memory for file headers!\n");
  426.        multi_error=1;
  427.        exit(1);
  428.     }
  429.     source_handle = open(name, O_RDONLY | O_BINARY);
  430.     if(source_handle == -1){
  431.        perror(msg);
  432.        printf("Couldn't open sound file %s\n",name);
  433.        multi_error=1;
  434.        return(99);
  435.        }
  436.     type=get_file_type(name);
  437.     switch( type )
  438.     {
  439.        case 'S':
  440.           read_tandy(&info, source_handle);
  441.           break;
  442.        case 'V':
  443.           read_voc(&info, source_handle);
  444.           break;
  445.        case 'W':
  446.           read_wav(&info, source_handle);
  447.           break;
  448.        case 'I':
  449.           read_iff(&info, source_handle);
  450.           break;
  451.        case 'A':
  452.           read_sam(&info, source_handle);
  453.           break;
  454.        case 'M':
  455.           ctsam=0;
  456.           read_mod(&info, source_handle);
  457.           break;
  458.        case '?':
  459.           read_unknown(&info, source_handle);
  460.           break;
  461.     }
  462.  
  463.     if(speaker(0))printf("DSP error turning off speaker\n");
  464.  
  465.     close(source_handle);
  466.     free(buffer);
  467.     free(fbuffer);
  468.     free(workbuf);
  469.     if(verbose)show_card_info();
  470.     return(error);
  471. }
  472.  
  473.     /* Determine type of Sound File by looking at file extension*/
  474.  
  475. char get_file_type(char *file_name)
  476. {
  477.     char *pdest;
  478.     char name[80];
  479.  
  480.     strcpy(name,file_name);
  481.  
  482.     if(strstr(name, ".SND")){
  483.       return('S');
  484.       }
  485.     if(strstr(name, ".WAV")){
  486.       return('W');
  487.       }
  488.     if(strstr(name, ".VOC")){
  489.       return('V');
  490.       }
  491.     if(strstr(name, ".IFF")){
  492.       return('I');
  493.       }
  494.     if(strstr(name, ".AIF")){
  495.       return('I');
  496.       }
  497.     if(strstr(name, ".SAM")){
  498.       return('A');
  499.       }
  500.     if(strstr(name, ".MOD")){
  501.       return('M');
  502.       }
  503.     return('?');
  504. }
  505.  
  506.     /* Read Sound File Information */
  507.     /* Tandy SND, VOC, WAV, & IFF Files Supported */
  508.  
  509. /* Tandy SND files */
  510.  
  511. int read_tandy(struct SOUND *hp, int source_handle)
  512. {
  513.     struct TANDY header;
  514.     struct TANDY_R n_sample[16];
  515.     struct OLDTANDY oldheader;
  516.     struct OLDTANDY_R o_sample[16];
  517.     long position=0;
  518.     int samples=0;
  519.     int i=0;
  520.  
  521.     hp->byte_format=INTEL;
  522.  
  523.     read(source_handle,&header, sizeof(struct TANDY));
  524.     if(header.id == 32794) {
  525.        hp->frequency=header.frequency;
  526.        samples=header.number_clips;
  527.        if(samples>16)samples=16;
  528.        if(verbose || file_info)printf("Tandy SND File %s",&header.name);
  529.        if(verbose || file_info)printf("\tcontains %i sound sample(s)\n",samples);
  530.        if(header.compression != 0)compression=TCOMP;
  531.        hp->bits=8;
  532.  
  533.        for(i=0; i<samples;i++){
  534.          read(source_handle,&n_sample[i],sizeof(struct TANDY_R));
  535.        }
  536.  
  537.        for(i=0; i<samples;i++){
  538.          hp->length=n_sample[i].length;
  539.          hp->number_samples=n_sample[i].number_samples;
  540.          position=n_sample[i].start;
  541.          lseek(source_handle,position,SEEK_SET);
  542.          play_block(hp,source_handle);
  543.          if(error)return(error);
  544.          }
  545.        }
  546.     else if(header.name[0] == 0x1a) {
  547.        lseek(source_handle,position,SEEK_SET);
  548.        read(source_handle,&oldheader, sizeof(struct OLDTANDY));
  549.        if(oldheader.id == 0x1A) {
  550.           hp->frequency=oldheader.frequency;
  551.           samples=oldheader.number_clips;
  552.           if(samples>16)samples=16;
  553.           if(verbose || file_info)printf("Old Tandy SND File %s",oldheader.name);
  554.           if(verbose || file_info)printf("\tcontains %i sound sample(s)\n",samples);
  555.           if(oldheader.compression != 0)compression=TCOMP;
  556.           hp->bits=8;
  557.  
  558.        for(i=0; i<samples;i++){
  559.          read(source_handle,&o_sample[i],sizeof(struct OLDTANDY_R));
  560.        }
  561.  
  562.           for(i=0;i<samples;i++){
  563.         hp->length=o_sample[i].length;
  564.         hp->number_samples=o_sample[i].number_samples;
  565.         position=o_sample[i].start;
  566.         lseek(source_handle,position,SEEK_SET);
  567.         play_block(hp,source_handle);
  568.         if(error)return(error);
  569.         }
  570.           }
  571.        }
  572.        else read_unknown(hp, source_handle);
  573. }
  574.  
  575. /* Creative Labs VOC files */
  576.  
  577. int read_voc(struct SOUND *hp, int source_handle)
  578. {
  579.     struct LABS header;
  580.     struct LABSV110 data;
  581.     struct LABSV120 ndata;
  582.  
  583.     char *pdest;
  584.     unsigned int temp=0;
  585.     unsigned long int temp1=0;
  586.     int terminate_not_found=1;
  587.     unsigned char type=0;
  588.     int bytes_read=0;
  589.     unsigned int period=0;
  590.     unsigned char tc=0;
  591.     unsigned int marker=0;
  592.     
  593.     hp->byte_format=INTEL;
  594.  
  595.     read(source_handle,&header, sizeof(struct LABS));
  596.     if(strstr(header.id , "Creative Voice File")){
  597.  
  598.        if(verbose || file_info)printf("Creative Labs ver %i.%i VOC file\n"
  599.        ,header.major_version,header.minor_version);
  600.  
  601.        hp->bits=8;
  602.  
  603.        do{
  604.           bytes_read=read(source_handle,&type,1);
  605.           if(bytes_read == 0)type=0;
  606.        switch(type)
  607.        {
  608.        case TERMINATE:
  609.           if(debug) printf("Terminate Block\n");
  610.           terminate_not_found=0;
  611.           break;
  612.        case VOICE:
  613.           if(debug) printf("Voice Block\n");
  614.           read(source_handle,&data, sizeof(struct LABSV110));
  615.           if(hp->channels == 1)
  616.           hp->frequency=(unsigned) (1000000 / (256-data.frequency));
  617.           else
  618.           hp->frequency=(unsigned) (500000 / (256-data.frequency));
  619.           temp=data.number_samples1;
  620.           temp=temp + data.number_samples2 * 256;
  621.           temp1=(unsigned long)(temp+ data.number_samples3 * 65536);
  622.           hp->length=temp1-2;
  623.           hp->number_samples=temp1-2;
  624.           switch (data.compression)
  625.           {
  626.           case 1:
  627.         compression=ADPCM4;
  628.         info.bits=4;
  629.         break;
  630.           case 2:
  631.         compression=ADPCM26;
  632.         info.bits=3;
  633.         break;
  634.           case 3:
  635.         compression=ADPCM2;
  636.         info.bits=2;
  637.         break;
  638.           }
  639.           play_block(hp,source_handle);
  640.           if(error)return(error);
  641.           break;
  642.        case CONTINUE:
  643.           if(debug) printf("Voice Continuation Block\n");
  644.           read(source_handle,buffer, 3);
  645.           temp=buffer[0];
  646.           temp=temp + buffer[1] * 256;
  647.           temp1=(unsigned long)(temp+ buffer[2] * 65536);
  648.           hp->length=(unsigned int)temp1;
  649.           play_block(hp,source_handle);
  650.           if(error)return(error);
  651.           break;
  652.        case SILENCE:
  653.           read(source_handle,buffer, 3);
  654.           read(source_handle,&period, sizeof(period));
  655.           read(source_handle,&tc, sizeof(tc));
  656.           if(debug) printf("Silence Block %x %x \n",tc,period);
  657.           if(!file_info)delay(tc,period);
  658.           if(error)return(error);
  659.           break;
  660.        case MARKER:
  661.           read(source_handle,buffer, 3);
  662.           read(source_handle,&marker, sizeof(marker));
  663.           if(debug) printf("Marker Block %x\n",marker);
  664.           break;
  665.        case ASCII:
  666.           if(debug) printf("ASCII Block\n");
  667.           read(source_handle,buffer, 3);
  668.           temp=buffer[0];
  669.           temp=temp + buffer[1] * 256;
  670.           temp1=(unsigned long)(temp+ buffer[2] * 65536);
  671.           temp=(unsigned int)temp1;
  672.           temp=read(source_handle,buffer, temp);
  673.           buffer[temp]=0;
  674.           if(verbose)printf("%s\n",buffer);
  675.           break;
  676.        case REPEAT:
  677.           read(source_handle,buffer, 3);
  678.           temp=buffer[0];
  679.           temp=temp + buffer[1] * 256;
  680.           temp1=(unsigned long)(temp+ buffer[2] * 65536);
  681.           temp=(unsigned int)temp1;
  682.           temp=read(source_handle,buffer, temp);
  683.           repeat=repeat+temp;
  684.           if(debug) printf("Repeat Block %i\n",repeat);
  685.           break;
  686.        case VOCEND:
  687.           if(debug) printf("End Repeat Block\n");
  688.           read(source_handle,buffer, 3);
  689.           break;
  690.        case EXTEND:
  691.           if(debug) printf("Extend Block\n");
  692.           read(source_handle,buffer, 3);
  693.           temp=buffer[0];
  694.           temp=temp + buffer[1] * 256;
  695.           temp1=(unsigned long)(temp+ buffer[2] * 65536);
  696.           temp=(unsigned int)temp1;
  697.           temp=read(source_handle,buffer, temp);
  698.           hp->channels=buffer[3]+1;
  699.           switch (data.compression)
  700.           {
  701.           case 1:
  702.         compression=ADPCM4;
  703.         info.bits=4;
  704.         break;
  705.           case 2:
  706.         compression=ADPCM26;
  707.         info.bits=3;
  708.         break;
  709.           case 3:
  710.         compression=ADPCM2;
  711.         info.bits=2;
  712.         break;
  713.           }
  714.           break;
  715.        case NEWVOC:
  716.           if(debug) printf("New Voice Block\n");
  717.           read(source_handle,&ndata, sizeof(struct LABSV120));
  718.           temp=(unsigned int)ndata.frequency1;
  719.           hp->frequency=(unsigned int)(ndata.frequency2 * 256 + temp);
  720.           temp=ndata.number_samples1;
  721.           temp=temp + ndata.number_samples2 * 256;
  722.           temp1=(unsigned long)(temp+ ndata.number_samples3 * 65536);
  723.           hp->length=temp1 - 12;
  724.           hp->bits=ndata.bits_per_sample;
  725.           hp->channels=ndata.channels;
  726.  
  727.           switch(ndata.compression)
  728.           {
  729.           case 0x00:
  730.          play_block(hp,source_handle);
  731.          if(error)return(error);
  732.          break;
  733.           case 0x01:
  734.          compression=ADPCM4;
  735.          info.bits=4;
  736.          play_block(hp,source_handle);
  737.          if(error)return(error);
  738.          break;
  739.           case 0x02:
  740.          compression=ADPCM26;
  741.          info.bits=3;
  742.          play_block(hp,source_handle);
  743.          if(error)return(error);
  744.          break;
  745.           case 0x03:
  746.          compression=ADPCM2;
  747.          info.bits=2;
  748.          play_block(hp,source_handle);
  749.          if(error)return(error);
  750.          break;
  751.           case 0x04:
  752.          hp->bits=-16;
  753.          play_block(hp,source_handle);
  754.          if(error)return(error);
  755.          break;
  756.           case 0x05:
  757.          play_block(hp,source_handle);
  758.          if(error)return(error);
  759.          break;
  760.           default:
  761.          if(debug)printf("Unknown Compression Type");
  762.          break;
  763.          }
  764.        default:
  765.           /* skip unwanted or unknown block data */
  766.           read(source_handle,buffer, 3);
  767.           temp=buffer[0];
  768.           temp=temp + buffer[1] * 256;
  769.           temp1=(unsigned long)(temp+ buffer[2] * 65536);
  770.           temp=(unsigned int)temp1;
  771.           temp=read(source_handle,buffer, temp);
  772.           if(debug)printf("Skipping Unknown Voc chunk of %u bytes\n",temp);
  773.           break;
  774.        }
  775.        }while(terminate_not_found);
  776.       }
  777.     else read_unknown(hp, source_handle);
  778. }
  779.  
  780.  
  781. /* Microsoft Wave Files */
  782.  
  783. int read_wav(struct SOUND *hp, int source_handle)
  784. {
  785.     struct RIFFWAVE riff;
  786.     struct SUBCHUNK subchunk;
  787.     struct WAVEfmt  * wavefmt;
  788.     struct RIFFLIST rifflist;
  789.     struct FACTinfo fact;
  790.  
  791.     int data_not_found=1;
  792.     unsigned long temp=0;
  793.  
  794.     hp->byte_format=INTEL;
  795.     temp=0;
  796.     read(source_handle,&riff,sizeof(struct RIFFWAVE));
  797.     if((riff.id==RIFF) && (riff.form_type==WAVE)){
  798.  
  799.     if(verbose || file_info)printf("Microsoft WAVE file\n");
  800.  
  801.          do{
  802.           read(source_handle,&subchunk,sizeof(struct SUBCHUNK));
  803.  
  804.           switch(subchunk.id)
  805.           {
  806.            case FMT:
  807.          wavefmt=(struct WAVEfmt *)malloc((int)subchunk.subchunk_size);
  808.          read(source_handle,wavefmt,(int)subchunk.subchunk_size);
  809.          switch(wavefmt->format_tag)
  810.          {
  811.           case  2:
  812.             compression=MSADPCM;
  813.             break;
  814.           case  6:
  815.             compression=ALAW;
  816.             info.bits=14;
  817.             break;
  818.           case  7:
  819.             compression=ULAW;
  820.             info.bits=14;
  821.             break;
  822.           case 17:
  823.             compression=ADPCM;
  824.             break;
  825.           case 512:
  826.             compression=ADPCM4;
  827.             break;
  828.           default:
  829.             break;
  830.          }
  831.          hp->bits=wavefmt->bits_per_sample;
  832.          if(wavefmt->bits_per_sample == 16)hp->bits= -16;
  833.          temp=(wavefmt->bytes_per_second*8/(wavefmt->channels*abs(hp->bits)));
  834.          hp->frequency=(unsigned)temp;
  835.          hp->channels=wavefmt->channels;
  836.          free(wavefmt);
  837.          break;
  838.            case WDATA:
  839.          hp->length=subchunk.subchunk_size;
  840.          error=play_block(hp,source_handle);
  841.          if(error)return(error);
  842.          data_not_found=0;
  843.          break;
  844.            case WLIST:
  845.          /* do nothing with data and read past to next chunk */
  846.          read(source_handle,buffer,(int)subchunk.subchunk_size);
  847.          break;
  848.            case FACT:
  849.          read(source_handle,&fact,(int)subchunk.subchunk_size);
  850.          hp->number_samples=fact.number_samples;
  851.          break;
  852.            default:
  853.          /* Skip unknown subchunk information */
  854.          read(source_handle,buffer,(int)subchunk.subchunk_size);
  855.          if(debug)printf("Skipping Unknown WAV Subchunk!\n");
  856.          break;
  857.  
  858.            }
  859.           } while(data_not_found);
  860.        }
  861.        else read_unknown(hp, source_handle);
  862. }
  863.  
  864. /* Apple & Electronic Arts IFF Sound Files */
  865.  
  866. int read_iff(struct SOUND *hp, int source_handle)
  867. {
  868.     struct SOUNDIFF iff;
  869.     struct SUBCHUNK subchunk;
  870.     struct IFFvhdr vhdr;
  871.     struct AIFFCOMM aiff;
  872.  
  873.     int data_not_found=1;
  874.     int temp=0;
  875.     unsigned int exponent=0;
  876.     unsigned int mantissa=0;
  877.     unsigned long l=0;
  878.  
  879.     hp->byte_format=MM;
  880.     read(source_handle,&iff,sizeof(struct SOUNDIFF));
  881.  
  882.     if(iff.id==FORM){
  883.  
  884.     if((verbose || file_info) && (iff.form_type==SVX))printf("Electronic Arts IFF file\n");
  885.     if((verbose || file_info) && (iff.form_type==AIFF))printf("Apple AIFF file\n");
  886.  
  887.          do{
  888.           read(source_handle,&subchunk,sizeof(struct SUBCHUNK));
  889.  
  890.           switch(subchunk.id)
  891.           {
  892.            case VHDR:
  893.          read(source_handle,&vhdr,(int)mm(subchunk.subchunk_size));
  894.          temp=vhdr.samples_per_second;
  895.          hp->frequency=(((temp & 0xff00L) >> 8) +
  896.           ((temp & 0x00ffL) << 8));
  897.          if(vhdr.compression != 0)compression=UNKNOWN;
  898.          break;
  899.            case COMM:
  900.          read(source_handle,&aiff,(int)mm(subchunk.subchunk_size));
  901.          hp->channels=mmi(aiff.channels);
  902.          hp->number_samples=mm(aiff.number_samples);
  903.          hp->bits=-mmi(aiff.bits_per_sample);
  904.          mmf(&aiff.frequency);
  905.          hp->frequency=(unsigned)aiff.frequency;
  906.          break;
  907.            case BODY:
  908.          hp->length=mm(subchunk.subchunk_size);
  909.          hp->bits= -8;
  910.          error=play_block(hp,source_handle);
  911.          if(error)return(error);
  912.          data_not_found=0;
  913.          break;
  914.            case SSND:
  915.          hp->length=mm(subchunk.subchunk_size);
  916.          error=play_block(hp,source_handle);
  917.          if(error)return(error);
  918.          data_not_found=0;
  919.          break;
  920.            case INST:
  921.          read(source_handle,buffer,(int)mm(subchunk.subchunk_size));
  922.          break;
  923.            case ANNO:
  924.          temp=(int)mm(subchunk.subchunk_size);
  925.          read(source_handle,buffer,temp);
  926.          buffer[temp]=0;
  927.          if(verbose)printf("%s\n",buffer);
  928.          break;
  929.            case AUTH:
  930.          temp=(int)mm(subchunk.subchunk_size);
  931.          read(source_handle,buffer,temp);
  932.          buffer[temp]=0;
  933.          if(verbose)printf("The author is %s\n",buffer);
  934.          break;
  935.            case NAME:
  936.          temp=(int)mm(subchunk.subchunk_size);
  937.          read(source_handle,buffer,temp);
  938.          buffer[temp]=0;
  939.          if(verbose)printf("Name is %s\n",buffer);
  940.          break;
  941.            default:
  942.          /* Skip unknown subchunk information */
  943.          read(source_handle,buffer,(int)mm(subchunk.subchunk_size));
  944.          if(debug)printf("Skipping Unknown IFF Subchunk!\n");
  945.          break;
  946.  
  947.            }
  948.           } while(data_not_found);
  949.        }
  950.        else read_unknown(hp, source_handle);
  951.  
  952. }
  953.  
  954. /* MOD SAMple file   */
  955.  
  956. int read_sam(struct SOUND *hp, int source_handle)
  957. {
  958.     long position=0;
  959.  
  960.     hp->byte_format=MM;
  961.     if(verbose || file_info) printf("Mod SAMple file.\n");
  962.     lseek(source_handle,position,SEEK_SET);
  963.     hp->bits= -8;
  964.     if(play_rate==11000)play_rate=8000;
  965.     hp->frequency=play_rate;
  966.     hp->length=filelength(source_handle);
  967.     error=play_block(hp,source_handle);
  968.     if(error)return(error);
  969. }
  970.  
  971. /* Amiga MOD file */
  972.  
  973. int read_mod(struct SOUND *hp, int source_handle)
  974. {
  975.     struct MODhdr header;
  976.     struct MODsample sample[31];
  977.     struct MODraw raw[31];
  978.     struct MODsong song;
  979.     int i=0;
  980.     int j=0;
  981.     int k=0;
  982.     int patch=0;                    /* Sample Number */
  983.     unsigned int note=0;            /* Note */
  984.     int effect=0;                   /* Effect Command */
  985.     int e_data=0;                   /* Effect Data */
  986.     int max=0;                      /* Number of 1024byte patterns */
  987.     int number_samples=0;
  988.     int max_sam=0;
  989.     int newmod=0;
  990.     long int n=0;
  991.     char *ppattern[128];
  992.     long position=1080;              /* check for type of Mod */
  993.     time_t p_time;
  994.     time_t c_time;
  995.  
  996.     hp->byte_format=MM;
  997.     lseek(source_handle,position,SEEK_SET);
  998.     read(source_handle,&n,sizeof(n));
  999.  
  1000.     switch(n)
  1001.     {
  1002.     case M_k_:
  1003.     case FLT4:
  1004.        max_sam=31;
  1005.        newmod=1;
  1006.     break;
  1007.     default:
  1008.        max_sam=15;
  1009.     break;
  1010.     }
  1011.     position=0;                        /* restore file pointer */
  1012.  
  1013.     lseek(source_handle,position,SEEK_SET);
  1014.  
  1015.     time(&p_time);
  1016.     read(source_handle,&header,sizeof(struct MODhdr));
  1017.     if((verbose || file_info) && header.name[0] != 0)printf("Module name is %.20s\n",
  1018.       &header.name);
  1019.        if(shell && file_info){
  1020.          time(&c_time);
  1021.          while((c_time-p_time) < 2){
  1022.           time(&c_time);
  1023.          };
  1024.        _settextposition(23,1);
  1025.        _outtext("                                                 ");
  1026.        _settextposition(23,1);
  1027.        };
  1028.     for(i=0;i < max_sam;i++){
  1029.       read(source_handle,&sample[i],sizeof(struct MODsample));
  1030.       n=0;
  1031.       n=(long)mmi(sample[i].number_samples)*2;
  1032.       raw[i].number_samples=n;
  1033.       if(debug && sample[i].name[0] != 0)printf("Sample %i\t%lu\t%.22s\n",
  1034.       i+1,n,sample[i].name);
  1035.     }
  1036.     j=0;
  1037.     read(source_handle,&song,sizeof(struct MODsong));
  1038.  
  1039.      j=(int)song.s_length;
  1040.      if(debug)printf("Song length is %i\t",j);
  1041.      if(newmod)read(source_handle,&n,sizeof(n));
  1042.      if(debug && newmod)printf("File id is %.4s\n",&n);
  1043.      for(i=0; i < j;i++){
  1044.        if((int)song.sequence[i] > max)max=(int)song.sequence[i];
  1045.        if(debug)printf("%i ",(int)song.sequence[i]);
  1046.      }
  1047.      max=max+1;
  1048.      if(debug)printf("\nNumber of Patterns is %i\n",max);
  1049.      for(i=0; i < max;i++){
  1050.        ppattern[i]=(char *)malloc(1024);
  1051.        if(ppattern[i] == NULL){
  1052.           printf("Not enough memory for patterns!\n");
  1053.           multi_error=1;
  1054.           exit(1);
  1055.        }
  1056.        k=read(source_handle,ppattern[i],1024);
  1057.        if(k != 1024){
  1058.          printf("Error reading pattern %u\n",k);
  1059.          multi_error=1;
  1060.        }
  1061.      }
  1062.  
  1063.     for(i=0; i<31;i++){
  1064.      raw[i].frequency=0;
  1065.     }
  1066.  
  1067.      for(i=0; i < max;i++){
  1068.        if(debug)printf("\nSample\tNote\tEffect\tData\tPattern %i\n\n",i+1);
  1069.        for(j=0; j < 1024;j=j+4){
  1070.         patch=(((*(ppattern[i]+j)&240) | ((*(ppattern[i]+j+2)&240) >> 4))&31);
  1071.         note=((((*(ppattern[i]+j)&15) << 8) | (*(ppattern[i]+j+1)&255)&1023));
  1072.         effect=(*(ppattern[i]+j+2)&15);
  1073.         e_data=(*(ppattern[i]+j+3)&255);
  1074.         if(debug && (note != 0))printf("%u\t%u\t%X\t%X\n",patch,note,
  1075.         effect,e_data);
  1076.         if(note != 0)raw[patch-1].frequency=note;
  1077.         if(debug){
  1078.           if(check_esc())goto exit_mod;
  1079.         }
  1080.        }
  1081.      }
  1082.      for(i=0; i < max_sam;i++){
  1083.      hp->bits=-8;
  1084.      hp->number_samples=raw[i].number_samples;
  1085.      hp->length=raw[i].number_samples;
  1086.       if(raw[i].number_samples > 0){
  1087.        if(check_esc())goto exit_mod;
  1088.        if(verbose)printf("\n");
  1089.        if(shell && file_info){
  1090.          _settextposition(23,1);
  1091.          _outtext("                                                 ");
  1092.          _outtext("                                                 ");
  1093.          _outtext("                                                 ");
  1094.          _settextposition(23,1);
  1095.        }
  1096.        if(verbose || file_info)printf("Sample %i\t%.22s\n",i+1,sample[i].name);
  1097.        j=(sample[i].finetune & 15);
  1098.        if ((j&8) == 8)j=j-16;
  1099.        if(debug)printf("Fine Tune =%i\tVolume=%i\n",
  1100.        j,(int)sample[i].volume);
  1101.        if(debug)printf("Repeat Start=%u\tRepeat Length=%u\n",
  1102.        mmi(sample[i].r_start)*2,mmi(sample[i].r_length)*2);
  1103.        if(raw[i].frequency == 0)raw[i].frequency=428;
  1104.        note=((55930/raw[i].frequency) <<  6);
  1105.        raw[i].frequency=note;
  1106.        hp->frequency=raw[i].frequency;
  1107.        error=play_block(hp,source_handle);
  1108.        if(error)break;
  1109.        if(rip)error=create_sam(raw[i].number_samples,source_handle);
  1110.        if(error)break;
  1111.       }
  1112.      }
  1113. exit_mod:
  1114.      for(i=0;i<max;i++)free(ppattern[i]);
  1115.      return(error);
  1116. }
  1117.  
  1118. int     read_steve(struct SOUND *hp, int source_handle)
  1119. {
  1120.     struct STEVE steve;
  1121.     long position=0;
  1122.     long int length=0;
  1123.  
  1124.     hp->byte_format=INTEL;
  1125.     lseek(source_handle,position,SEEK_SET);
  1126.  
  1127.     read(source_handle,&steve,sizeof(struct STEVE));
  1128.  
  1129.     if(verbose || file_info)printf("STEVE Sound file\n");
  1130.     conversion_table=0;
  1131.     hp->length=steve.number_samples;
  1132.     if(steve.version==2)hp->frequency=steve.frequency;
  1133.     else hp->frequency=8900;
  1134.     error=play_block(hp,source_handle);
  1135.     return(error);
  1136. }
  1137.  
  1138. /* Check for MAC, AU, WAV, STEVE files by looking for Header */
  1139.  
  1140. int read_unknown(struct SOUND *hp, int source_handle)
  1141. {
  1142.     union unknown_header
  1143.     {
  1144.     struct MACBINARY mac_header;
  1145.     struct SOUNDIFF iff;
  1146.     struct SUN au_header;
  1147.     struct RIFFWAVE riff;
  1148.     struct LABS labs;
  1149.     struct STEVE steve;
  1150.     } snd;
  1151.  
  1152.     long position=0;
  1153.  
  1154.     lseek(source_handle,position,SEEK_SET);
  1155.  
  1156.     read(source_handle,&snd.mac_header,MAX_HEADER);
  1157.  
  1158.     if(snd.mac_header.type==MACTYPE)read_mac(hp,source_handle);
  1159.  
  1160.     else
  1161.       if(snd.au_header.id==AU_SND)read_au(hp,source_handle);
  1162.  
  1163.     else
  1164.       if((snd.riff.id==RIFF) && (snd.riff.form_type==WAVE)){
  1165.         lseek(source_handle,position,SEEK_SET);
  1166.         read_wav(hp,source_handle);
  1167.       }
  1168.  
  1169.     else
  1170.       if(strstr(snd.labs.id , "Creative Voice File")){
  1171.         lseek(source_handle,position,SEEK_SET);
  1172.         read_voc(hp,source_handle);
  1173.       }
  1174.  
  1175.     else
  1176.       if(strstr(snd.steve.id , "STEVE")){
  1177.         lseek(source_handle,position,SEEK_SET);
  1178.         read_steve(hp,source_handle);
  1179.       }
  1180.  
  1181.     else
  1182.       if(snd.iff.id==FORM){
  1183.         lseek(source_handle,position,SEEK_SET);
  1184.         read_iff(hp,source_handle);
  1185.       }
  1186.  
  1187.     else{
  1188.       if(verbose || file_info) printf("Unknown file format using defaults for playback.\n");
  1189.       hp->byte_format=INTEL;
  1190.       lseek(source_handle,position,SEEK_SET);
  1191.       error=play_block(hp,source_handle);
  1192.       if(error)return(error);
  1193.       }
  1194. }
  1195.  
  1196. int read_mac(struct SOUND *hp, int source_handle)
  1197. {
  1198.     struct MACBINARY mac_header;
  1199.     long position=0;
  1200.     long int length=0;
  1201.     long int mac_comp=0;
  1202.  
  1203.     hp->byte_format=MM;
  1204.     lseek(source_handle,position,SEEK_SET);
  1205.  
  1206.     read(source_handle,&mac_header,sizeof(struct MACBINARY));
  1207.  
  1208.     if(verbose || file_info)printf("MAC Sound file %s\n",&mac_header.name);
  1209.     length=mm(mac_header.datafork_size);
  1210.     hp->length=length-4;
  1211.     hp->number_samples=length;
  1212.     hp->bits=8;
  1213.     read(source_handle,&mac_comp,sizeof(mac_comp));
  1214.     if(mac_comp==HCOM)compression=HCOM;
  1215.     error=play_block(hp,source_handle);
  1216.     return(error);
  1217. }
  1218.  
  1219. int read_au(struct SOUND *hp, int source_handle)
  1220. {
  1221.     struct SUN au_header;
  1222.     long position=0;
  1223.     long int length=0;
  1224.     long au_type=0;
  1225.  
  1226.     hp->byte_format=MM;
  1227.     lseek(source_handle,position,SEEK_SET);
  1228.  
  1229.     read(source_handle,&au_header,sizeof(struct SUN));
  1230.  
  1231.     if(verbose || file_info)printf("SUN au file\n");
  1232.     hp->length=mm(au_header.data_size);
  1233.     hp->number_samples=mm(au_header.data_size);
  1234.     hp->frequency=mm(au_header.frequency);
  1235.     hp->channels=mm(au_header.channels);
  1236.     au_type=mm(au_header.compression);
  1237.     switch(au_type)
  1238.     {
  1239.     case 1:
  1240.       info.bits= 14;
  1241.       compression=ULAW;
  1242.       break;
  1243.     case 2:
  1244.       hp->bits=-8;
  1245.       break;
  1246.     case 3:
  1247.       hp->bits= -16;
  1248.       break;
  1249.     default:
  1250.       if(debug)printf("Unknown or not supported .au file\n");
  1251.       break;
  1252.     }
  1253.     position=mm(au_header.chunk_size);
  1254.  
  1255.     lseek(source_handle,position,SEEK_SET);
  1256.     error=play_block(hp,source_handle);
  1257.     if(error)return(error);
  1258. }
  1259.  
  1260. int play_block(struct SOUND *hp, int source_handle)
  1261. {
  1262.     long i=0;
  1263.     long l=0;
  1264.     long freq=0;
  1265.     int type_comp=0;
  1266.     unsigned j=0;
  1267.     unsigned nb=0;
  1268.     unsigned k=0;
  1269.     unsigned block_size=0;
  1270.     unsigned int m=0;
  1271.     unsigned num_blocks=0;
  1272.     long number_read=0;
  1273.     unsigned frequency=0;
  1274.     int thru=0;
  1275.     long num_samples=0;
  1276.     time_t c_time;
  1277.     time_t p_time;
  1278.     int file_error=0;
  1279.  
  1280.     if(hp->length ==0)hp->length=hp->number_samples;
  1281.     if(hp->length ==0)hp->length=filelength(source_handle);
  1282.     if(hp->bits ==0)hp->bits=default_bits;
  1283.     if(hp->number_samples ==0){
  1284.       i=hp->length*8/(abs(hp->bits));
  1285.       hp->number_samples=i;
  1286.     }
  1287.  
  1288.     /* Check for 0 Playback Rate */
  1289.  
  1290.     if(hp->frequency == 0)hp->frequency=play_rate;
  1291.  
  1292.     num_samples=hp->length;
  1293.     type_comp=compression;
  1294.     
  1295.     if(hp->channels==0){
  1296.       hp->channels=1;
  1297.       printf("Defaulting to single channel\n");
  1298.     }
  1299.  
  1300.     if(check_esc()){
  1301.       error=-1;
  1302.       goto exit_playblock;
  1303.     }
  1304.  
  1305.     if(!thru)print_file_info(hp);
  1306.     time(&p_time);
  1307.  
  1308.     /* Play all samples */
  1309.  
  1310.     do{
  1311.  
  1312.     if(check_esc()){
  1313.       error=-1;
  1314.       goto exit_playblock;
  1315.     }
  1316.  
  1317.  
  1318.     hp->length=num_samples;
  1319.     compression=type_comp;
  1320.  
  1321.     /* Allocate memory for sound data */
  1322.  
  1323.     j=0;
  1324.     i=0;
  1325.     pp=0;
  1326.     k=block_size=dma_size;
  1327.  
  1328.     if(emm_present){
  1329.       k=block_size=dma_size=16384;
  1330.       emm_win_size=1;
  1331.     }
  1332.     l=hp->length;
  1333.  
  1334.     do{
  1335.       if(emm_present){
  1336.         emm_pages_req=(num_samples/(long)16384)+1;
  1337.         if(emm_pages_req > emm_pages_free){
  1338.           emm_pages_req=emm_pages_free;
  1339.           hp->length=(long)emm_pages_free * (long)16384;
  1340.         }
  1341.         if(emm_pages_req < emm_win_size)emm_win_size=emm_pages_req-1;
  1342.         if(emm_error=EMM_alloc_pages(emm_pages_req))
  1343.           printf("Error %x allocating %i EMS pages\n",emm_error,
  1344.         emm_pages_req);
  1345.         multi_error=1;
  1346.         num_blocks=emm_pages_req;
  1347.         i=(long)emm_pages_req * (long)16384;
  1348.         break;
  1349.       }
  1350.       else
  1351.        if((fbuffer[j] =(char *)_fmalloc((size_t)k)) == NULL){
  1352.           num_blocks=j;
  1353.           hp->length=(long)num_blocks * (long)(dma_size);
  1354.           break;
  1355.        }
  1356.        j++;
  1357.        i+=k;
  1358.     } while(i < hp->length);
  1359.  
  1360.     num_samples-=i;
  1361.  
  1362.     /* Read Sound File Data into Memory */
  1363.  
  1364.     j=0;
  1365.     m=0;
  1366.     nb=0;
  1367.     pp=0;
  1368.     k=dma_size;
  1369.     number_read=0;
  1370.     l=hp->length;
  1371.  
  1372.     do
  1373.     {
  1374.       if(l < (long)k) k=l;
  1375.       if(emm_present){
  1376.        for(p=0; p < emm_win_size; p++){
  1377.          if(emm_error=EMM_map_page(p,pp)){
  1378.            printf("Error %x mapping page %i %i for reading\n",emm_error,p,pp);
  1379.            multi_error=1;
  1380.          }
  1381.          pp++;
  1382.        }
  1383.        m = read(source_handle,emm_page[0],k);
  1384.        }
  1385.       else
  1386.        m = read(source_handle,fbuffer[j],k);
  1387.       j++;
  1388.       nb++;
  1389.       number_read+=m;
  1390.       l-=k;
  1391.     } while((number_read < hp->length) && m==k);
  1392.     hp->length = number_read;
  1393.  
  1394.       if(!file_info){
  1395.  
  1396. /* Check for compressed files */
  1397.  
  1398.     if(compression){
  1399.  
  1400.       switch(compression)
  1401.       {
  1402.       case ULAW:
  1403.        hp->bits= -16;
  1404.        j=0;
  1405.        i=0;
  1406.        pp=0;
  1407.        l=hp->length;
  1408.        k=block_size;
  1409.  
  1410.        do
  1411.        {
  1412.         if(l < (long)k)k=l;
  1413.         if(emm_present){
  1414.           for(p=0; p < emm_win_size; p++){
  1415.         if(emm_error=EMM_map_page(p,pp)){
  1416.          printf("Error %x mapping page %i %i for ulaw\n",emm_error,p,pp);
  1417.          multi_error=1;
  1418.         }
  1419.         pp++;
  1420.           }
  1421.           uncompress_ulaw(emm_page[0],k);
  1422.         }
  1423.         else
  1424.           uncompress_ulaw(fbuffer[j],k);
  1425.           l-=k;
  1426.           i+=k;
  1427.           j++;
  1428.        } while(i < hp->length);
  1429.        if(debug)printf("Converted %lu ULAW samples to 8 bit data\n",i);
  1430.        break;
  1431.       case ALAW:
  1432.        hp->bits= -16;
  1433.        j=0;
  1434.        i=0;
  1435.        pp=0;
  1436.        l=hp->length;
  1437.        k=block_size;
  1438.        do
  1439.        {
  1440.         if(l < (long)k)k=l;
  1441.         if(emm_present){
  1442.           for(p=0; p < emm_win_size; p++){
  1443.            if(emm_error=EMM_map_page(p,pp)){
  1444.         printf("Error %x mapping page %i %i for alaw\n",emm_error,p,pp);
  1445.         multi_error=1;
  1446.            }
  1447.            pp++;
  1448.            }
  1449.          uncompress_alaw(emm_page[0],k);
  1450.         }
  1451.         else
  1452.           uncompress_alaw(fbuffer[j],k);
  1453.         l-=k;
  1454.         i+=k;
  1455.         j++;
  1456.        } while(i < hp->length);
  1457.        if(debug)printf("Converted %lu ALAW samples to 8 bit data\n",i);
  1458.        break;
  1459.       }
  1460.     }
  1461.  
  1462. /* Convert 16 bit to 8 bit data */
  1463.  
  1464.     if((hp->bits > 8) || (hp->bits <  -8) && !compression){
  1465.       j=0;
  1466.       i=0;
  1467.       pp=0;
  1468.       l=hp->length;
  1469.       k=block_size;
  1470.       info.bits=-16;
  1471.       do
  1472.       {
  1473.         if(l < (long)k)k=l;
  1474.         if(emm_present){
  1475.          for(p=0; p < emm_win_size; p++){
  1476.            if(emm_error=EMM_map_page(p,pp)){
  1477.         printf("Error %x mapping page %i %i for 8 bit\n",emm_error,p,pp);
  1478.         multi_error=1;
  1479.            }
  1480.            pp++;
  1481.          }
  1482.          to_8bit(emm_page[0],k,hp->byte_format);
  1483.         }
  1484.         else
  1485.           to_8bit(fbuffer[j],k,hp->byte_format);
  1486.           j++;
  1487.           i+=k;
  1488.           l-=k;
  1489.       } while(i < hp->length);
  1490.       if(debug)printf("Converted %lu samples to 8 bit data\n",i);
  1491.       hp->length=hp->length/2;
  1492.       block_size=block_size/2;
  1493.     }
  1494.  
  1495. /* Convert Data to Unsigned 8 bit if required */
  1496.  
  1497.     j=0;
  1498.     i=0;
  1499.     pp=0;
  1500.     l=hp->length;
  1501.     k=block_size;
  1502.  
  1503.     if(hp->bits < 0){
  1504.       do
  1505.       {
  1506.         if(l < (long)k)k=l;
  1507.         if(emm_present){
  1508.          for(p=0; p < emm_win_size; p++){
  1509.            if(emm_error=EMM_map_page(p,pp)){
  1510.         printf("Error %x mapping page %i %i for unsigned\n",emm_error,p,pp);
  1511.         multi_error=1;
  1512.            }
  1513.            pp++;
  1514.          }
  1515.          to_unsigned(emm_page[0],k);
  1516.         }
  1517.         else
  1518.           to_unsigned(fbuffer[j],k);
  1519.           j++;
  1520.           i+=k;
  1521.           l-=k;
  1522.       } while(i < hp->length);
  1523.     if(debug)printf("Converted %lu samples to unsigned data\n",i);
  1524.     }
  1525.  
  1526. /* Decrease Amplitude if desired */
  1527.  
  1528.     if(magnitude < 0){
  1529.       i=0;
  1530.       pp=0;
  1531.       j=0;
  1532.       l=hp->length;
  1533.       k=block_size;
  1534.     do
  1535.       {
  1536.         if(l < (long)k)k=l;
  1537.         if(emm_present){
  1538.          for(p=0; p < emm_win_size; p++){
  1539.            if(emm_error=EMM_map_page(p,pp)){
  1540.         printf("Error %x mapping page %i %i for min gain\n",emm_error,p,pp);
  1541.         multi_error=1;
  1542.            }
  1543.         pp++;
  1544.          }
  1545.          m_gain(emm_page[0],k);
  1546.         }
  1547.         else
  1548.           m_gain(fbuffer[j],k);
  1549.           j++;
  1550.           i+=k;
  1551.           l-=k;
  1552.       } while(i < hp->length);
  1553.     if(debug)printf("%lu samples silenced\n",i);
  1554.     }
  1555.  
  1556. /* Increase Amplitude if desired */
  1557.  
  1558.     if(magnitude > 0){
  1559.       i=0;
  1560.       j=0;
  1561.       pp=0;
  1562.       l=hp->length;
  1563.       k=block_size;
  1564.       do
  1565.       {
  1566.         if(l < (long)k)k=l;
  1567.         if(emm_present){
  1568.          for(p=0; p < emm_win_size; p++){
  1569.            if(emm_error=EMM_map_page(p,pp)){
  1570.         printf("Error %x mapping page %i %i for plus gain\n",emm_error,p,pp);
  1571.         multi_error=1;
  1572.            }
  1573.         pp++;
  1574.          }
  1575.          p_gain(emm_page[0],k);
  1576.         }
  1577.         else
  1578.           p_gain(fbuffer[j],k);
  1579.           j++;
  1580.           i+=k;
  1581.           l-=k;
  1582.       } while(i < hp->length);
  1583.       if(debug)printf("%lu samples amplified\n",i);
  1584.     }
  1585.  
  1586.     frequency=hp->frequency;
  1587.  
  1588. /* Double Playback Frequency for stereo files */
  1589.  
  1590.     freq=hp->frequency;
  1591.  
  1592.     if(hp->channels==2){
  1593.       freq=hp->frequency*2;
  1594.       frequency=hp->frequency *2;
  1595.       card_info.mode=card_info.mode=(card_info.mode | BIT8_S);
  1596.     }
  1597.  
  1598. /* Halve Playback Frequency if greater than 22,050 Hertz */
  1599.  
  1600.     while (freq > 22050 )
  1601.     {
  1602.     j=0;
  1603.     i=0;
  1604.     pp=0;
  1605.     l=hp->length;
  1606.     k=block_size;
  1607.       do
  1608.       {
  1609.         if(l < (long)k)k=l;
  1610.         if(emm_present){
  1611.          for(p=0; p < emm_win_size; p++){
  1612.            if(emm_error=EMM_map_page(p,pp)){
  1613.         printf("Error %x mapping page %i %i for down\n",emm_error,p,pp);
  1614.         multi_error=1;
  1615.            }
  1616.         pp++;
  1617.          }
  1618.          down_sample(emm_page[0],k);
  1619.         }
  1620.         else
  1621.           down_sample(fbuffer[j],k);
  1622.           j++;
  1623.           i+=k;
  1624.           l-=k;
  1625.       } while(i < hp->length);
  1626.     if(debug)printf("Down sampling %lu samples @%lu hertz\n",i,freq);
  1627.     block_size=block_size/2;
  1628.     freq=freq/2;
  1629.     hp->length=hp->length/2;
  1630.     frequency=freq;
  1631.     }
  1632.  
  1633.     /* Skip playback if doing file conversion */
  1634.  
  1635.     if(ctwav)file_error=create_wav(hp->length, block_size,(unsigned)frequency);
  1636.     else if(ctsam)file_error=create_raw(hp->length, block_size,(unsigned)frequency);
  1637.     else if(ctvoc)file_error=create_voc(hp->length, block_size,(unsigned)frequency);
  1638.     else if(ctsnd)file_error=create_snd(hp->length, block_size,(unsigned)frequency);
  1639.     else{
  1640.  
  1641. /* Play Back Sound Samples on DAC if available */
  1642. /* else play back on regular PC speaker              */
  1643.  
  1644.     if(speaker(1))printf("DSP error turning on speaker\n");
  1645.  
  1646.  
  1647. /* Play Back Sound Samples */
  1648.  
  1649.     compression=(compression & 0xffcf);     /* ULAW & ALAW ok */
  1650.  
  1651. /* display error message for compressed files */
  1652.  
  1653.     if(compression)error=compression;
  1654.     card_info.mode=(card_info.mode | compression);
  1655.  
  1656.     if(verbose && (card_info.type!=PCSPEAKER) && !compression){
  1657.       if(!thru)printf("\nUse the <Esc> key to stop playback!\n\n");
  1658.     }
  1659.     if(shell && (card_info.type!=PCSPEAKER)){
  1660.       _settextcolor(14);
  1661.       _settextposition(23,1);
  1662.       _outtext("                                                                ");
  1663.       _settextposition(24,10);
  1664.       _outtext("Use the <Esc> key to stop playback!");
  1665.       _settextposition(25,1);
  1666.       _outtext("                                                                ");
  1667.       _settextposition(23,1);
  1668.     }
  1669.  
  1670.     do
  1671.     {
  1672.       i=0;
  1673.       j=0;
  1674.       pp=0;
  1675.       l=hp->length;
  1676.       if(repeat > 0)repeat--;
  1677.       k=block_size;
  1678.  
  1679.       do
  1680.       {
  1681.         if(l < (long)k)k=l;
  1682.         if(k>0){
  1683.          if(card_info.type!=PCSPEAKER){
  1684.           if(emm_present){
  1685.            for(p=0; p < emm_win_size; p++){
  1686.         if(emm_error=EMM_map_page(p,pp)){
  1687.          printf("Error %x mapping page %i %i for dac\n",emm_error,p,pp);
  1688.          multi_error=1;
  1689.         }
  1690.         pp++;
  1691.         }
  1692.            error=dacplay(emm_page[0],k,frequency,card_info.mode,volume,hp->channels);
  1693.            }
  1694.           else
  1695.         error=dacplay((char _far *)fbuffer[j],k,frequency,card_info.mode,volume,hp->channels);
  1696.           }
  1697.          else if(!compression){
  1698.         if(shell){
  1699.           _settextcolor(14);
  1700.           _settextposition(24,15);
  1701.           _outtext("Please wait while playing!");
  1702.           _settextposition(23,1);
  1703.         }
  1704.           if(emm_present){
  1705.            for(p=0; p < emm_win_size; p++){
  1706.         if(emm_error=EMM_map_page(p,pp)){
  1707.          ("Error %x mapping page %i %i for pcplay\n",emm_error,p,pp);
  1708.          multi_error=1;
  1709.         }
  1710.         pp++;
  1711.         }
  1712.            error=pcplay(emm_page[0],k,frequency,conversion_table,pitch);
  1713.            }
  1714.           else
  1715.           error=pcplay((char _far *)fbuffer[j],k,frequency,conversion_table,pitch);
  1716.          }
  1717.          else error=NOCOMPRESS;
  1718.         }
  1719.         j++;
  1720.         i+=k;
  1721.         l-=k;
  1722.     } while((j < nb) && !error);
  1723.       if(error)repeat=0;
  1724.     } while(repeat > 0);
  1725.  
  1726.     /* Reset delay used by pcplay after each sound file */
  1727.  
  1728.     if(card_info.type==PCSPEAKER){
  1729.      pcplay(emm_page[0],0,frequency,conversion_table,pitch);
  1730.     }
  1731.       } /* End of ctwav or ctsam */
  1732.       }
  1733.  
  1734.       j=nb;
  1735.  
  1736.     if(!emm_present){
  1737.       do{
  1738.         j--;
  1739.         if(fbuffer[j]!=NULL){
  1740.          _ffree(fbuffer[j]);
  1741.         }
  1742.       } while(j > 0);
  1743.     }
  1744.     if(error > 0 && error!=NOCOMPRESS)show_dac_error(error);
  1745.  
  1746.     if(error < 0){
  1747.      if(!shell)printf("Sound output ended!\n");
  1748.      stop=TRUE;
  1749.     }
  1750.     repeat=1;
  1751.     thru+=1;
  1752.  
  1753.     /* Deallocate EMS memory */
  1754.  
  1755.     if(emm_present){
  1756.       if(emm_error=EMM_release_pages()){
  1757.          printf("Error %x releasing EMS memory\n",emm_error);
  1758.          multi_error=1;
  1759.       }
  1760.     }
  1761.  
  1762.     } while((num_samples > 0) && !error);
  1763.  
  1764.     if(error==NOCOMPRESS && (card_info.type==PCSPEAKER)){
  1765.       if(shell){
  1766.         _settextcolor(14);
  1767.         _settextposition(24,1);
  1768.         _outtext("Type of compression not supported by PC speaker!");
  1769.       }
  1770.       else
  1771.         printf("Type of compression not supported by PC speaker!\n");
  1772.     }
  1773.        if(shell && file_info){
  1774.          time(&c_time);
  1775.          while((c_time-p_time) < 2){
  1776.           time(&c_time);
  1777.          }
  1778.        }
  1779. exit_playblock:
  1780.     hp->number_samples=0;
  1781.     multi_error=file_error;
  1782.     append=0;
  1783.     return(error);
  1784. }
  1785.  
  1786.  
  1787. /* convert Little Endian to Big Endian (Motorolla to Intel) */
  1788.  
  1789. long mm(long l)
  1790. {
  1791.  
  1792.     return(((l & 0xff000000L) >> 24) +
  1793.            ((l & 0x00ff0000L) >> 8) +
  1794.            ((l & 0x0000ff00L) << 8) +
  1795.            ((l & 0x000000ffL) << 24));
  1796. }
  1797.  
  1798. /* convert little Endian INT to Big Endian (MM to intel) */
  1799.  
  1800. unsigned int mmi(unsigned int n)
  1801. {
  1802.     return(((n & 0xff00) >> 8) + ((n & 0x00ff) << 8));
  1803. }
  1804.  
  1805. /* convert Little Endian to Big Endian (Motorolla to Intel) */
  1806.  
  1807. void mmf(double long *i)
  1808. {
  1809.     unsigned j=0;
  1810.     unsigned k=9;
  1811.     char *number;
  1812.     char temp[12];
  1813.  
  1814.     number=(char *)i;
  1815.  
  1816.     for(j=0;j<10;j++){
  1817.        temp[j]=number[k];
  1818.        k--;
  1819.     }
  1820.     for(j=0;j<10;j++){
  1821.     *((char *)i+j)=temp[j];
  1822.     }
  1823. }
  1824.  
  1825. /* convert to unsigned int */
  1826.  
  1827. void to_unsigned(char _far *hp,unsigned int k)
  1828. {
  1829.     unsigned int i=0;
  1830.  
  1831.     if(&hp==NULL){
  1832.       printf("Convert to unsigned pointer error\n");
  1833.       multi_error=1;
  1834.       return;
  1835.     }
  1836.     if(k<1){
  1837.       printf("Convert to unsigned int error\n");
  1838.       multi_error=1;
  1839.       return;
  1840.     }
  1841.     do
  1842.     {
  1843.     hp[i]=hp[i]+128;
  1844.     i++;
  1845.     } while(i < k);
  1846. }
  1847.  
  1848. /* convert to signed int */
  1849.  
  1850. void to_signed(char _far *hp,unsigned int k)
  1851. {
  1852.     unsigned int i=0;
  1853.  
  1854.     if(&hp==NULL){
  1855.       printf("Convert to signed pointer error\n");
  1856.       multi_error=1;
  1857.       return;
  1858.     }
  1859.     if(k<1){
  1860.       printf("Convert to signed int error\n");
  1861.       multi_error=1;
  1862.       return;
  1863.     }
  1864.     do
  1865.     {
  1866.     hp[i]=hp[i]-128;
  1867.     i++;
  1868.     } while(i < k);
  1869. }
  1870.  
  1871. /* convert 16 bit to 8 bit data */
  1872.  
  1873. void to_8bit(char _far *hp, unsigned int k,signed int byte_format)
  1874. {
  1875.     unsigned int i=0;
  1876.     unsigned int j=0;
  1877.     int n=1;
  1878.  
  1879.     if(&hp==NULL){
  1880.       printf("Convert to 8 bit pointer error\n");
  1881.       multi_error=1;
  1882.       return;
  1883.     }
  1884.     if(k<1){
  1885.       printf("Convert to 8 bit int error\n");
  1886.       multi_error=1;
  1887.       return;
  1888.     }
  1889.     if(byte_format==INTEL)n=1;
  1890.     if(byte_format==MM)n=0;
  1891.     do
  1892.     {
  1893.     hp[i]=hp[j+n];
  1894.     i++;
  1895.     j++;
  1896.     j++;
  1897.     } while(j < k);
  1898. }
  1899.  
  1900. void down_sample(char _far *hp, unsigned int k)
  1901. {
  1902.     unsigned int i=0;
  1903.     unsigned int j=0;
  1904.  
  1905.     if(&hp==NULL){
  1906.       printf("Down sample pointer error\n");
  1907.       multi_error=1;
  1908.       return;
  1909.     }
  1910.     if(k<1){
  1911.       printf("Down sample int error\n");
  1912.       multi_error=1;
  1913.       return;
  1914.     }
  1915.     do
  1916.     {
  1917.     hp[i]=hp[j];
  1918.     i++;
  1919.     j++;
  1920.     hp[i]=hp[j];
  1921.     i++;
  1922.     j+=3;
  1923.     } while(j < k);
  1924. }
  1925.  
  1926. int m_gain(unsigned char _far *hp, unsigned int k)
  1927. {
  1928.     unsigned int i=0;
  1929.  
  1930.     if(&hp==NULL){
  1931.       printf("m_gain pointer error\n");
  1932.       multi_error=1;
  1933.       return(-1);
  1934.     }
  1935.     if(k<1){
  1936.       printf("m_gain int error\n");
  1937.       multi_error=1;
  1938.       return(-1);
  1939.     }
  1940.     do
  1941.     {
  1942.     hp[i]=((hp[i]-128) >> 1)+128;
  1943.     i++;
  1944.     } while(i < k);
  1945. }
  1946.  
  1947. int p_gain(unsigned char _far *hp, unsigned int k)
  1948. {
  1949.     unsigned int i=0;
  1950.  
  1951.     if(&hp==NULL){
  1952.       printf("p_gain pointer error\n");
  1953.       multi_error=1;
  1954.       return(-1);
  1955.     }
  1956.     if(k<1){
  1957.       printf("p_gain int error\n");
  1958.       multi_error=1;
  1959.       return(-1);
  1960.     }
  1961.     do
  1962.     {
  1963.     hp[i]=((hp[i]-128) << 1)+128;
  1964.     i++;
  1965.     } while(i < k);
  1966. }
  1967.  
  1968. /* Change Default Playback Rate for unknown files */
  1969.  
  1970. void get_speed(char *pdest)
  1971. {
  1972.     char command;
  1973.  
  1974.     sscanf(pdest,"%c%c%u",&command,&command,&play_rate);
  1975.     if(debug)printf("Default Playback Rate changed to %u hz\n",play_rate);
  1976. }
  1977.  
  1978. /* Get Virtual DMA size in k(1024) */
  1979.  
  1980. unsigned get_dma_size(void)
  1981. {
  1982.     unsigned int dma_buffer_size=0;
  1983.  
  1984.     _asm{
  1985.     push di
  1986.     push si
  1987.     mov ax,354bh            ; Check for INT 4b vector
  1988.     int 21h                 ; Call DOS to get it
  1989.     mov dx,es
  1990.     cmp dx,0
  1991.     je no_irq               ; Skip if vector is zero
  1992.     mov ax,8102h            ; Call DMA services to find
  1993.     mov dx,0                ; buffer size
  1994.     int 4bh
  1995.     jnc dpm
  1996. no_irq: mov ax,64000            ; If Virtual DMA Function not available
  1997.     mov dx,0                ; use 64k buffer
  1998.     jmp gdexit
  1999. dpm:
  2000.     mov ax,si
  2001.     mov cx,7
  2002.     shl ax,cl
  2003.     mov cx,10
  2004.     mov bx,di
  2005.     shr bx,cl
  2006.     add ax,bx
  2007. gdexit:
  2008.     mov dma_buffer_size,ax
  2009.     pop si
  2010.     pop di
  2011.     }
  2012.     return(dma_buffer_size);
  2013. }
  2014.  
  2015. /* Print File Information if wanted */
  2016.  
  2017. int print_file_info(struct SOUND *hp)
  2018. {
  2019.     int i=0;
  2020.  
  2021.     if(shell)_settextposition(24,1);
  2022.     i=abs(info.bits);
  2023.     if(verbose || file_info){
  2024.        printf("%i Bit",i);
  2025.        if(hp->channels==1)printf(" Mono");
  2026.        if(hp->channels==2)printf(" Stereo");
  2027.        if(hp->bits < 0)printf(" Signed Data  ");
  2028.        if(hp->bits >= 0)printf(" Unsigned Data");
  2029.        printf("\tFrequency: %u hz\n",hp->frequency);
  2030.        printf("Number of samples: %lu  \t",hp->number_samples/hp->channels);
  2031.        if(compression){
  2032.         switch(compression)
  2033.         {
  2034.           case ADPCM4:
  2035.         printf("4-Bit ADPCM Compression");
  2036.         break;
  2037.           case ADPCM26:
  2038.         printf("2.6-Bit ADPCM Compression");
  2039.         break;
  2040.           case ADPCM2:
  2041.         printf("2-Bit ADPCM Compression");
  2042.         break;
  2043.           case ALAW:
  2044.         printf("ALAW Compression");
  2045.         break;
  2046.           case ADPCM:
  2047.         printf("ADPCM Compression");
  2048.         break;
  2049.           case MSADPCM:
  2050.         printf("MSADPCM Compression");
  2051.         break;
  2052.           case TCOMP:
  2053.         printf("Tandy Compression");
  2054.         break;
  2055.           case ULAW:
  2056.         printf("ULAW Compression");
  2057.         break;
  2058.           default:
  2059.         printf("Unknown Compression");
  2060.         break;
  2061.         }}
  2062.        if(!shell)printf("\n");
  2063.        }
  2064. }
  2065.  
  2066. int create_sam(long samples, int source_handle)
  2067. {
  2068.     int key=0;
  2069.     char name[80];
  2070.     char *file_name;
  2071.     char *file_buffer;
  2072.     int handle;
  2073.     long position=0;
  2074.     long number_read=0;
  2075.     int j,k,m;
  2076.  
  2077.     if(shell){
  2078.       _settextcolor(14);
  2079.       _settextposition(24,1);
  2080.       _outtext("                                                       ");
  2081.       _settextposition(23,1);
  2082.     }
  2083.     printf("\nDo you want to create a SAM file of this sample? (N/y)");
  2084.     key=getch();
  2085.     if(shell){
  2086.       _settextposition(24,1);
  2087.       _outtext("                                                       ");
  2088.       _settextposition(23,1);
  2089.     }
  2090.     switch(key)
  2091.     {
  2092.     case 'Y':
  2093.     case 'y':
  2094.        printf("\nPlease enter file name to use: ");
  2095.        gets(name);
  2096.        if(name != NULL){
  2097.          strupr(name);
  2098.          file_name=strrchr(name,'.');
  2099.          if(file_name==NULL)strcat(name,".SAM");
  2100.          handle = open(name, O_CREAT | O_RDWR | O_EXCL | O_BINARY,
  2101.                   S_IREAD | S_IWRITE);
  2102.          if(handle == -1){
  2103.          if( errno == EEXIST )
  2104.         {
  2105.          if(shell){
  2106.          _settextposition(24,1);
  2107.          _outtext("                                                       ");
  2108.          _settextposition(24,1);
  2109.          }
  2110.           cputs( "File already exists. Overwrite (N/y)? " );
  2111.           key = getch();
  2112.           if( (key == 'y') || (key == 'Y') )
  2113.           handle = open( name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC,
  2114.                     S_IREAD | S_IWRITE );
  2115.           printf( "\n" );
  2116.         }
  2117.         else{
  2118.          p_cerror(msg,name);
  2119.          return(99);
  2120.          }
  2121.         }
  2122.         if( (key == 'y') || (key == 'Y') ){
  2123.          if((file_buffer =(char *)malloc(8192)) == NULL){
  2124.          perror(msg);
  2125.          printf("Malloc could not allocate memory for file buffer.\n");
  2126.          error=1;
  2127.          }
  2128.          position=lseek(source_handle,-samples,SEEK_CUR);
  2129.          if(position==-1)perror(msg);
  2130.  
  2131.     j=0;
  2132.     m=0;
  2133.     k=0;
  2134.     number_read=0;
  2135.     
  2136.     if(shell){
  2137.       _settextposition(23,1);
  2138.       printf("\n                                                      ");
  2139.     }
  2140.     do
  2141.     {
  2142.       if(samples - number_read > 8192) k=8192;
  2143.        else k=samples - number_read;
  2144.       m = read(source_handle,file_buffer,k);
  2145.       j = write(handle,file_buffer,k);
  2146.       if(debug)printf("%u samples read & %u samples written to file.\n",m,j);
  2147.       if(m!=j){
  2148.         printf("File write problem.\n");
  2149.         multi_error=1;
  2150.       }
  2151.       number_read=number_read + m;
  2152.     } while((number_read < samples) && m==k);
  2153.          free(file_buffer);
  2154.          close(handle);
  2155.        }
  2156.        break;
  2157.     }
  2158.     return(error);
  2159.     }
  2160.     return(0);
  2161. }
  2162.  
  2163. int create_wav(long samples, unsigned int block_size, unsigned int frequency)
  2164. {
  2165.     struct wav_header
  2166.     {
  2167.     struct RIFFWAVE riff;
  2168.     struct SUBCHUNK fmt;
  2169.     struct WAVEfmt wavefmt;
  2170.     struct SUBCHUNK subchunk;
  2171.     } header;
  2172.  
  2173.     int key=0;
  2174.     int error=0;
  2175.     char name[80];
  2176.     char *file_name;
  2177.     int handle;
  2178.     int b=0;
  2179.     unsigned int m=0;
  2180.     long int i,j,k,l,n,t;
  2181.  
  2182.     /* initialize header values */
  2183.  
  2184.     header.riff.id=RIFF;
  2185.     header.riff.chunk_size=samples+sizeof(header);
  2186.     header.riff.form_type=WAVE;
  2187.     header.fmt.id=FMT;
  2188.     header.fmt.subchunk_size=sizeof(header.wavefmt);
  2189.     if(compression==ADPCM4)header.wavefmt.format_tag=512;
  2190.     else header.wavefmt.format_tag=BIT8_M;
  2191.     header.wavefmt.channels=1;
  2192.     header.wavefmt.number_samples_per_second=11025;
  2193.     header.wavefmt.bytes_per_second=11025;
  2194.     header.wavefmt.block_align=1;
  2195.     header.wavefmt.bits_per_sample=8;
  2196.     header.subchunk.id=WDATA;
  2197.     header.subchunk.subchunk_size=samples;
  2198.  
  2199.     if(append==0){
  2200.     if(shell){
  2201.       _settextcolor(14);
  2202.       _settextposition(24,1);
  2203.       _outtext("                                                       ");
  2204.       _settextposition(23,1);
  2205.     }
  2206.  
  2207.     printf("\nDo you want to create a WAV file? (N/y)");
  2208.     key=getch();
  2209.  
  2210.     if(shell){
  2211.       _settextposition(24,1);
  2212.       _outtext("                                                       ");
  2213.       _settextposition(23,1);
  2214.     }
  2215.     }
  2216.     else{
  2217.     key='A';
  2218.     }
  2219.     switch(key)
  2220.     {
  2221.     case 'Y':
  2222.     case 'y':
  2223.        printf("\nPlease enter file name to use: ");
  2224.        gets(name);
  2225.        if(name != NULL){
  2226.          strupr(name);
  2227.          file_name=strrchr(name,'.');
  2228.          if(file_name==NULL)strcat(name,".WAV");
  2229.          strcpy(a_file_name,name);
  2230.          handle = open(name, O_CREAT | O_RDWR | O_EXCL | O_BINARY,
  2231.                   S_IREAD | S_IWRITE);
  2232.          if(handle == -1){
  2233.            if( errno == EEXIST ){
  2234.         if(shell){
  2235.          _settextposition(24,1);
  2236.          _outtext("                                                       ");
  2237.          _settextposition(24,1);
  2238.          }
  2239.         cputs( "File already exists. Overwrite (N/y)? " );
  2240.         key = getch();
  2241.         if( (key == 'y') || (key == 'Y') )
  2242.           handle = open( name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC,
  2243.                     S_IREAD | S_IWRITE );
  2244.         printf( "\n" );
  2245.            }
  2246.          else{
  2247.            p_cerror(msg,name);
  2248.            return(99);
  2249.          }
  2250.         }
  2251.         if( (key == 'y') || (key == 'Y') ){
  2252.           if(shell){
  2253.         _settextposition(24,1);
  2254.         _outtext("                                                       ");
  2255.         _settextposition(23,1);
  2256.            }
  2257.  
  2258.     /* Write WAVE header */
  2259.  
  2260.     m=write(handle,&header,sizeof(header));
  2261.     if(m!=sizeof(header)){
  2262.       printf("Problem writing WAVE header\n");
  2263.       multi_error=1;
  2264.     }
  2265.     case 'A':
  2266.     if(append!=0){
  2267.        handle=open(a_file_name,O_APPEND | O_RDWR | O_EXCL | O_BINARY,
  2268.              S_IREAD | S_IWRITE);
  2269.     }
  2270.     i=0;
  2271.     j=0;
  2272.     pp=0;
  2273.     n=0;
  2274.     t=0;
  2275.     b=0;
  2276.     m=0;
  2277.     l=samples;
  2278.     k=block_size;
  2279.  
  2280.     do
  2281.     {
  2282.       if(l < (long)k)k=l;
  2283.       if(k>0){
  2284.         if(emm_present){
  2285.            for(p=0; p < emm_win_size; p++){
  2286.         if(emm_error=EMM_map_page(p,pp)){
  2287.           printf("Error %x mapping page %i %i for ctwav\n",emm_error,p,pp);
  2288.           multi_error=1;
  2289.         }
  2290.         pp++;
  2291.            }
  2292.            if(frequency!=11025){
  2293.          n=change_frequency(emm_page[0],(unsigned)k,(unsigned)frequency,11025);
  2294.          m=write(handle,(char *)workbuf,(unsigned)n);
  2295.            }
  2296.            else m=write(handle,(char *)emm_page[0],(int)k);
  2297.          }
  2298.          else{
  2299.            if(frequency!=11025){
  2300.           n=change_frequency(fbuffer[b],(unsigned)k,(unsigned)frequency,11025);
  2301.           m=write(handle,(char *)workbuf,(unsigned)n);
  2302.            }
  2303.            else m=write(handle,fbuffer[b],(int)k);
  2304.          }
  2305.        i+=k;
  2306.        j+=m;
  2307.        t+=n;
  2308.        l-=k;
  2309.        b++;
  2310.       }
  2311.     } while(i < samples);
  2312.  
  2313.     if(debug)printf("%lu samples written to file.\n",j);
  2314.       close(handle);
  2315.       handle = open(a_file_name, O_RDWR | O_EXCL | O_BINARY,
  2316.             S_IREAD | S_IWRITE);
  2317.       if(handle == -1){
  2318.        perror(msg);
  2319.        printf("Couldn't open sound file %s\n",name);
  2320.        multi_error=1;
  2321.        }
  2322.       lseek(handle,0,SEEK_SET);
  2323.       append+=j;
  2324.       header.riff.chunk_size=sizeof(header)+append;
  2325.       header.subchunk.subchunk_size=append;
  2326.       m=write(handle,&header,sizeof(header));
  2327.     close(handle);
  2328.     }
  2329.     break;
  2330.     }
  2331.     return(error);
  2332.     }
  2333.     return(error);
  2334. }
  2335.  
  2336. int create_voc(long samples, unsigned int block_size, unsigned int frequency)
  2337. {
  2338.     struct voc_header
  2339.     {
  2340.     struct LABS labs;
  2341.     char chunk;
  2342.     struct LABSV110 v110;
  2343.     } header;
  2344.  
  2345.     int key=0;
  2346.     int error=0;
  2347.     char name[80];
  2348.     char *file_name;
  2349.     int handle;
  2350.     int b=0;
  2351.     unsigned int m=0;
  2352.     char terminate=0;
  2353.     long int i,j,k,l,n,t;
  2354.  
  2355.     /* initialize header values */
  2356.  
  2357.     strcpy(header.labs.id,"Creative Voice File");
  2358.     header.labs.id[20]=0x1a;
  2359.     header.labs.magic=0x1a;
  2360.     header.labs.offset=0x1a;
  2361.     header.labs.minor_version=0;
  2362.     header.labs.major_version=1;
  2363.     header.labs.type=0x1133;
  2364.     header.chunk=1;
  2365.     header.v110.number_samples1=0;
  2366.     header.v110.number_samples2=0;
  2367.     header.v110.number_samples3=0;
  2368.     header.v110.frequency=0xa6;
  2369.     header.v110.compression=0;
  2370.  
  2371.     if(append==0){
  2372.     if(shell){
  2373.       _settextcolor(14);
  2374.       _settextposition(24,1);
  2375.       _outtext("                                                       ");
  2376.       _settextposition(23,1);
  2377.     }
  2378.  
  2379.     printf("\nDo you want to create a VOC file? (N/y)");
  2380.     key=getch();
  2381.  
  2382.     if(shell){
  2383.       _settextposition(24,1);
  2384.       _outtext("                                                       ");
  2385.       _settextposition(23,1);
  2386.     }
  2387.     }
  2388.     else{
  2389.     key='A';
  2390.     }
  2391.     switch(key)
  2392.     {
  2393.     case 'Y':
  2394.     case 'y':
  2395.        printf("\nPlease enter file name to use: ");
  2396.        gets(name);
  2397.        if(name != NULL){
  2398.          strupr(name);
  2399.          file_name=strrchr(name,'.');
  2400.          if(file_name==NULL)strcat(name,".VOC");
  2401.          strcpy(a_file_name,name);
  2402.          handle = open(name, O_CREAT | O_RDWR | O_EXCL | O_BINARY,
  2403.                   S_IREAD | S_IWRITE);
  2404.          if(handle == -1){
  2405.            if( errno == EEXIST ){
  2406.         if(shell){
  2407.          _settextposition(24,1);
  2408.          _outtext("                                                       ");
  2409.          _settextposition(24,1);
  2410.          }
  2411.         cputs( "File already exists. Overwrite (N/y)? " );
  2412.         key = getch();
  2413.         if( (key == 'y') || (key == 'Y') )
  2414.           handle = open( name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC,
  2415.                     S_IREAD | S_IWRITE );
  2416.         printf( "\n" );
  2417.            }
  2418.          else{
  2419.            p_cerror(msg,name);
  2420.            return(99);
  2421.          }
  2422.         }
  2423.         if( (key == 'y') || (key == 'Y') ){
  2424.           if(shell){
  2425.         _settextposition(24,1);
  2426.         _outtext("                                                       ");
  2427.         _settextposition(23,1);
  2428.            }
  2429.  
  2430.     /* Write VOC header */
  2431.  
  2432.     m=write(handle,&header,sizeof(header));
  2433.     if(m!=sizeof(header)){
  2434.       printf("Problem writing VOC header\n");
  2435.       multi_error=1;
  2436.     }
  2437.     case 'A':
  2438.     if(append!=0){
  2439.        handle=open(a_file_name,O_APPEND | O_RDWR | O_EXCL | O_BINARY,
  2440.              S_IREAD | S_IWRITE);
  2441.     }
  2442.     i=0;
  2443.     j=0;
  2444.     pp=0;
  2445.     n=0;
  2446.     t=0;
  2447.     b=0;
  2448.     m=0;
  2449.     l=samples;
  2450.     k=block_size;
  2451.  
  2452.     do
  2453.     {
  2454.       if(l < (long)k)k=l;
  2455.       if(k>0){
  2456.         if(emm_present){
  2457.            for(p=0; p < emm_win_size; p++){
  2458.         if(emm_error=EMM_map_page(p,pp)){
  2459.           printf("Error %x mapping page %i %i for ctvoc\n",emm_error,p,pp);
  2460.           multi_error=1;
  2461.         }
  2462.         pp++;
  2463.            }
  2464.            if(frequency!=11111){
  2465.          n=change_frequency(emm_page[0],(unsigned)k,(unsigned)frequency,11111);
  2466.          m=write(handle,(char *)workbuf,(unsigned)n);
  2467.            }
  2468.            else m=write(handle,(char *)emm_page[0],(int)k);
  2469.          }
  2470.          else{
  2471.            if(frequency!=11111){
  2472.           n=change_frequency(fbuffer[b],(unsigned)k,(unsigned)frequency,11111);
  2473.           m=write(handle,(char *)workbuf,(unsigned)n);
  2474.            }
  2475.            else m=write(handle,fbuffer[b],(int)k);
  2476.          }
  2477.        i+=k;
  2478.        j+=m;
  2479.        t+=n;
  2480.        l-=k;
  2481.        b++;
  2482.       }
  2483.     } while(i < samples);
  2484.  
  2485.     if(debug)printf("%lu samples written to file.\n",j);
  2486.  
  2487.     /* Write Terminate Marker */
  2488.  
  2489.     write(handle,&terminate,1);
  2490.  
  2491.     close(handle);
  2492.       handle = open(a_file_name, O_RDWR | O_EXCL | O_BINARY,
  2493.             S_IREAD | S_IWRITE);
  2494.       if(handle == -1){
  2495.        perror(msg);
  2496.        printf("Couldn't open sound file %s\n",name);
  2497.        multi_error=1;
  2498.        }
  2499.  
  2500.     j+=2;
  2501.     append+=j;
  2502.     header.v110.number_samples1=(char)((append & 0x000000ff));
  2503.     header.v110.number_samples2=(char)((append & 0x0000ff00) >> 8);
  2504.     header.v110.number_samples3=(char)((append & 0x00ff0000) >> 16);
  2505.     lseek(handle,0,SEEK_SET);
  2506.     m=write(handle,&header,sizeof(header));
  2507.     close(handle);
  2508.     }
  2509.     break;
  2510.     }
  2511.     return(error);
  2512.     }
  2513.     return(error);
  2514. }
  2515.  
  2516.  
  2517. int create_raw(long samples, unsigned int block_size, unsigned int frequency)
  2518. {
  2519.     int key=0;
  2520.     int error=0;
  2521.     char name[80];
  2522.     char *file_name;
  2523.     int handle;
  2524.     int b=0;
  2525.     unsigned int m=0;
  2526.     long int i,j,k,l,n,t;
  2527.  
  2528.     if(append==0){
  2529.     if(shell){
  2530.       _settextcolor(14);
  2531.       _settextposition(24,1);
  2532.       _outtext("                                                       ");
  2533.       _settextposition(23,1);
  2534.     }
  2535.  
  2536.     printf("\nDo you want to create a SAM file? (N/y)");
  2537.  
  2538.     key=getch();
  2539.  
  2540.     if(shell){
  2541.       _settextposition(24,1);
  2542.       _outtext("                                                       ");
  2543.       _settextposition(23,1);
  2544.     }
  2545.     }
  2546.     else{
  2547.      key='A';
  2548.     }
  2549.     switch(key)
  2550.     {
  2551.     case 'Y':
  2552.     case 'y':
  2553.        printf("\nPlease enter file name to use: ");
  2554.        gets(name);
  2555.        if(name != NULL){
  2556.          strupr(name);
  2557.          file_name=strrchr(name,'.');
  2558.          if(file_name==NULL)strcat(name,".SAM");
  2559.          strcpy(a_file_name,name);
  2560.          handle = open(name, O_CREAT | O_RDWR | O_EXCL | O_BINARY,
  2561.                   S_IREAD | S_IWRITE);
  2562.          if(handle == -1){
  2563.            if( errno == EEXIST ){
  2564.         if(shell){
  2565.          _settextposition(24,1);
  2566.          _outtext("                                                       ");
  2567.          _settextposition(24,1);
  2568.          }
  2569.         cputs( "File already exists. Overwrite (N/y)? " );
  2570.         key = getch();
  2571.         if( (key == 'y') || (key == 'Y') )
  2572.           handle = open( name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC,
  2573.                     S_IREAD | S_IWRITE );
  2574.         printf( "\n" );
  2575.            }
  2576.          else{
  2577.            p_cerror(msg,name);
  2578.            return(99);
  2579.          }
  2580.         }
  2581.         if( (key == 'y') || (key == 'Y') ){
  2582.           if(shell){
  2583.         _settextposition(24,1);
  2584.         _outtext("                                                       ");
  2585.         _settextposition(23,1);
  2586.            }
  2587.  
  2588.     case 'A':
  2589.     if(append!=0){
  2590.        handle=open(a_file_name,O_APPEND | O_RDWR | O_EXCL | O_BINARY,
  2591.              S_IREAD | S_IWRITE);
  2592.     }
  2593.  
  2594.     i=0;
  2595.     j=0;
  2596.     pp=0;
  2597.     n=0;
  2598.     t=0;
  2599.     b=0;
  2600.     m=0;
  2601.     l=samples;
  2602.     k=block_size;
  2603.  
  2604.     do
  2605.     {
  2606.       if(l < (long)k)k=l;
  2607.       if(k>0){
  2608.         if(emm_present){
  2609.            for(p=0; p < emm_win_size; p++){
  2610.         if(emm_error=EMM_map_page(p,pp)){
  2611.           printf("Error %x mapping page %i %i for ctsam\n",emm_error,p,pp);
  2612.           multi_error=1;
  2613.         }
  2614.         pp++;
  2615.            }
  2616.            to_signed(emm_page[0],(unsigned)k);
  2617.            if(frequency!=8000){
  2618.          n=change_frequency(emm_page[0],(unsigned)k,(unsigned)frequency,8000);
  2619.          m=write(handle,(char *)workbuf,(unsigned)n);
  2620.            }
  2621.            else m=write(handle,(char *)emm_page[0],(int)k);
  2622.          }
  2623.          else{
  2624.            to_signed(fbuffer[b],(unsigned)k);
  2625.            if(frequency!=8000){
  2626.           n=change_frequency(fbuffer[b],(unsigned)k,(unsigned)frequency,8000);
  2627.           m=write(handle,(char *)workbuf,(unsigned)n);
  2628.            }
  2629.            else m=write(handle,fbuffer[b],(int)k);
  2630.          }
  2631.        i+=k;
  2632.        j+=m;
  2633.        t+=n;
  2634.        l-=k;
  2635.        b++;
  2636.       }
  2637.     } while(i < samples);
  2638.  
  2639.     append+=j;
  2640.     if(debug)printf("%lu samples written to file.\n",j);
  2641.     close(handle);
  2642.     }
  2643.     break;
  2644.     }
  2645.     return(error);
  2646.     }
  2647.     return(error);
  2648. }
  2649.  
  2650. int create_snd(long samples, unsigned int block_size, unsigned int frequency)
  2651. {
  2652.     struct tandy_header
  2653.     {
  2654.     struct OLDTANDY t_head;
  2655.     struct OLDTANDY_R t_record;
  2656.     } header;
  2657.  
  2658.     int key=0;
  2659.     int error=0;
  2660.     char name[80];
  2661.     char *file_name;
  2662.     int handle;
  2663.     int b=0;
  2664.     unsigned int m=0;
  2665.     long int i,j,k,l,n,t;
  2666.  
  2667.     /* initialize header values */
  2668.  
  2669.     header.t_head.id=0x1a;
  2670.     header.t_head.compression=0;
  2671.     header.t_head.number_clips=1;
  2672.     header.t_head.voice=0;
  2673.     strcpy(header.t_head.name,"         ");
  2674.     header.t_head.frequency=frequency;
  2675.     header.t_record.type=TANDY_type;
  2676.     header.t_record.start=sizeof(header);
  2677.     header.t_record.length=0;
  2678.     header.t_record.number_samples=samples;
  2679.     header.t_record.unknown=0;
  2680.     header.t_record.unknown1=0;
  2681.     header.t_record.unknown2=0;
  2682.  
  2683.     if(append==0){
  2684.     if(shell){
  2685.       _settextcolor(14);
  2686.       _settextposition(24,1);
  2687.       _outtext("                                                       ");
  2688.       _settextposition(23,1);
  2689.     }
  2690.  
  2691.     printf("\nDo you want to create a SND file? (N/y)");
  2692.     key=getch();
  2693.  
  2694.     if(shell){
  2695.       _settextposition(24,1);
  2696.       _outtext("                                                       ");
  2697.       _settextposition(23,1);
  2698.     }
  2699.     }
  2700.     else{
  2701.     key='A';
  2702.     }
  2703.     switch(key)
  2704.     {
  2705.     case 'Y':
  2706.     case 'y':
  2707.        printf("\nPlease enter file name to use: ");
  2708.        gets(name);
  2709.        if(name != NULL){
  2710.          strupr(name);
  2711.          file_name=strrchr(name,'.');
  2712.          if(file_name==NULL)strcat(name,".SND");
  2713.          strcpy(a_file_name,name);
  2714.          handle = open(name, O_CREAT | O_RDWR | O_EXCL | O_BINARY,
  2715.                   S_IREAD | S_IWRITE);
  2716.          if(handle == -1){
  2717.            if( errno == EEXIST ){
  2718.         if(shell){
  2719.          _settextposition(24,1);
  2720.          _outtext("                                                       ");
  2721.          _settextposition(24,1);
  2722.          }
  2723.         cputs( "File already exists. Overwrite (N/y)? " );
  2724.         key = getch();
  2725.         if( (key == 'y') || (key == 'Y') )
  2726.           handle = open( name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC,
  2727.                     S_IREAD | S_IWRITE );
  2728.         printf( "\n" );
  2729.            }
  2730.          else{
  2731.            p_cerror(msg,name);
  2732.            return(99);
  2733.          }
  2734.         }
  2735.         if( (key == 'y') || (key == 'Y') ){
  2736.           if(shell){
  2737.         _settextposition(24,1);
  2738.         _outtext("                                                       ");
  2739.         _settextposition(23,1);
  2740.            }
  2741.  
  2742.     /* Write old TANDY SND header */
  2743.  
  2744.     m=write(handle,&header,sizeof(header));
  2745.     if(m!=sizeof(header)){
  2746.       printf("Problem writing TANDY header\n");
  2747.       multi_error=1;
  2748.     }
  2749.     case 'A':
  2750.     if(append!=0){
  2751.        handle=open(a_file_name,O_APPEND | O_RDWR | O_EXCL | O_BINARY,
  2752.              S_IREAD | S_IWRITE);
  2753.     }
  2754.     i=0;
  2755.     j=0;
  2756.     pp=0;
  2757.     n=0;
  2758.     t=0;
  2759.     b=0;
  2760.     m=0;
  2761.     l=samples;
  2762.     k=block_size;
  2763.  
  2764.     do
  2765.     {
  2766.       if(l < (long)k)k=l;
  2767.       if(k>0){
  2768.         if(emm_present){
  2769.            for(p=0; p < emm_win_size; p++){
  2770.         if(emm_error=EMM_map_page(p,pp)){
  2771.           printf("Error %x mapping page %i %i for ctsam\n",emm_error,p,pp);
  2772.           multi_error=1;
  2773.         }
  2774.         pp++;
  2775.            }
  2776.            if(frequency!=11000){
  2777.          n=change_frequency(emm_page[0],(unsigned)k,(unsigned)frequency,11000);
  2778.          m=write(handle,(char *)workbuf,(unsigned)n);
  2779.            }
  2780.            else m=write(handle,(char *)emm_page[0],(int)k);
  2781.          }
  2782.          else{
  2783.            if(frequency!=11000){
  2784.           n=change_frequency(fbuffer[b],(unsigned)k,(unsigned)frequency,11000);
  2785.           m=write(handle,(char *)workbuf,(unsigned)n);
  2786.            }
  2787.            else m=write(handle,fbuffer[b],(int)k);
  2788.          }
  2789.        i+=k;
  2790.        j+=m;
  2791.        t+=n;
  2792.        l-=k;
  2793.        b++;
  2794.       }
  2795.     } while(i < samples);
  2796.  
  2797.     if(debug)printf("%lu samples written to file.\n",j);
  2798.     close(handle);
  2799.       handle = open(a_file_name, O_RDWR | O_EXCL | O_BINARY,
  2800.             S_IREAD | S_IWRITE);
  2801.       if(handle == -1){
  2802.        perror(msg);
  2803.        printf("Couldn't open sound file %s\n",name);
  2804.        multi_error=1;
  2805.        }
  2806.  
  2807.     append+=j;
  2808.     header.t_head.frequency=11000;
  2809.     header.t_record.number_samples=append;
  2810.     lseek(handle,0,SEEK_SET);
  2811.     m=write(handle,&header,sizeof(header));
  2812.     close(handle);
  2813.     }
  2814.     break;
  2815.     }
  2816.     return(error);
  2817.     }
  2818.     return(error);
  2819. }
  2820.  
  2821.  
  2822. /* Change frequency of samples to freq */
  2823.  
  2824. unsigned int change_frequency(char _far *hp,unsigned int k,unsigned int freq,unsigned int nfreq)
  2825. {
  2826.     unsigned int i=0;
  2827.     unsigned int new_k;
  2828.     long int temp=0;
  2829.     temp=(long)nfreq*k;
  2830.     new_k=temp/freq;
  2831.     i=0;
  2832.  
  2833.     do{
  2834.       workbuf[i]=*(hp+((long)freq*i/nfreq));
  2835.       i++;
  2836.     }while(i < new_k);
  2837.     return(i);
  2838. }
  2839.  
  2840. /* Uncompress ULAW to 8 bit data */
  2841.  
  2842. int uncompress_ulaw(char _far *hp, unsigned int number_samples)
  2843. {
  2844.     int ulaw_table[256]={
  2845.     -124,-120,-116,-112,-108,-104,-100,-96,
  2846.     -92,-88,-84,-80,-76,-72,-68,-64,
  2847.     -62,-60,-58,-56,-54,-52,-50,-48,
  2848.     -46,-44,-42,-40,-38,-36,-34,-32,
  2849.     -31,-30,-29,-28,-27,-26,-25,-24,
  2850.     -23,-22,-21,-20,-19,-18,-17,-16,
  2851.     -15,-15,-14,-14,-13,-12,-12,-12,
  2852.     -11,-10,-10,-10,-9,-8,-8,-8,
  2853.     -7,-7,-7,-7,-6,-6,-6,-6,
  2854.     -5,-5,-5,-5,-4,-4,-4,-4,
  2855.     -3,-3,-3,-3,-3,-3,-3,-3,
  2856.     -2,-2,-2,-2,-2,-2,-2,-2,
  2857.     -1,-1,-1,-1,-1,-1,-1,-1,
  2858.     -1,-1,-1,-1,-1,-1,-1,-1,
  2859.     0,0,0,0,0,0,0,0,
  2860.     0,0,0,0,0,0,0,0,
  2861.     124,120,116,112,108,104,100,96,
  2862.     92,88,84,80,76,72,68,64,
  2863.     62,60,58,56,54,52,50,48,
  2864.     46,44,42,40,38,36,34,32,
  2865.     31,30,29,28,27,26,25,24,
  2866.     23,22,21,20,19,18,17,16,
  2867.     15,15,14,14,13,12,12,12,
  2868.     11,10,10,10,9,8,8,8,
  2869.     7,7,7,7,6,6,6,6,
  2870.     5,5,5,5,4,4,4,4,
  2871.     3,3,3,3,3,3,3,3,
  2872.     2,2,2,2,2,2,2,2,
  2873.     1,1,1,1,1,1,1,1,
  2874.     1,1,1,1,1,1,1,1,
  2875.     0,0,0,0,0,0,0,0,
  2876.     0,0,0,0,0,0,0,0};
  2877.  
  2878.     unsigned int i=0;
  2879.  
  2880.     do
  2881.     {
  2882.       hp[i]=ulaw_table[(hp[i] & 0xff)];
  2883.     i++;
  2884.     } while(i < number_samples);
  2885. }
  2886.  
  2887. /* Uncompress ALAW to 8 bit data */
  2888.  
  2889. int uncompress_alaw(char _far *hp, unsigned int number_samples)
  2890. {
  2891.     int alaw_table[256]={
  2892.     -22,-21,-24,-23,-18,-17,-20,-19,
  2893.     -30,-29,-32,-31,-26,-25,-28,-27,
  2894.     -11,-10,-12,-11,-9,-8,-10,-9,
  2895.     -15,-14,-16,-15,-13,-12,-14,-13,
  2896.     -86,-82,-94,-90,-70,-66,-78,-74,
  2897.     -118,-114,-126,-122,-102,-98,-110,-106,
  2898.     -43,-41,-47,-45,-35,-33,-39,-37,
  2899.     -59,-57,-63,-61,-51,-49,-55,-53,
  2900.     -1,-1,-1,-1,-1,-1,-1,-1,
  2901.     -2,-2,-2,-2,-2,-2,-2,-2,
  2902.     0,0,0,0,0,0,0,0,
  2903.     -1,-1,-1,-1,-1,-1,-1,-1,
  2904.     -5,-5,-6,-6,-4,-4,-5,-5,
  2905.     -7,-7,-8,-7,-6,-6,-7,-7,
  2906.     -3,-3,-3,-3,-2,-2,-2,-2,
  2907.     -4,-4,-4,-4,-3,-3,-3,-3,
  2908.     22,21,24,23,18,17,20,19,
  2909.     30,29,32,31,26,25,28,27,
  2910.     11,10,12,11,9,8,10,9,
  2911.     15,14,16,15,13,12,14,13,
  2912.     86,82,94,90,70,66,78,74,
  2913.     118,114,126,122,102,98,110,106,
  2914.     43,41,47,45,35,33,39,37,
  2915.     59,57,63,61,51,49,55,53,
  2916.     1,1,1,1,1,1,1,1,
  2917.     2,2,2,2,2,2,2,2,
  2918.     0,0,0,0,0,0,0,0,
  2919.     1,1,1,1,1,1,1,1,
  2920.     5,5,6,6,4,4,5,5,
  2921.     7,7,8,7,6,6,7,7,
  2922.     3,3,3,3,2,2,2,2,
  2923.     4,4,4,4,3,3,3,3};
  2924.  
  2925.     unsigned int i=0;
  2926.  
  2927.     do
  2928.     {
  2929.       hp[i]=alaw_table[(hp[i] & 0xff)];
  2930.     i++;
  2931.     } while(i < number_samples);
  2932. }
  2933.  
  2934.  
  2935. int get_names(char *rnp, char *file_name)
  2936. {
  2937.     struct find_t find;
  2938.     char *rn;
  2939.  
  2940.     rn=rnp;
  2941.     if(!_dos_findfirst(file_name,_A_NORMAL, &find)){
  2942.        strcpy(rn,find.name);
  2943.        rn+=14;
  2944.        while(!_dos_findnext(&find)){
  2945.          strcpy(rn,find.name);
  2946.          rn+=14;
  2947.        }
  2948.     }
  2949.     return(0);
  2950. }
  2951.  
  2952. /* Change Default Volume */
  2953.  
  2954. void get_volume(char *pdest)
  2955. {
  2956.     char command;
  2957.  
  2958.     sscanf(pdest,"%c%c%ui",&command,&command,&volume);
  2959.     volume=(volume & MAXVOLUME);
  2960.     if(debug)printf("Volume changed to %u\n",volume);
  2961. }
  2962.  
  2963. void get_num_repeats(char *pdest)
  2964. {
  2965.     char command;
  2966.  
  2967.     sscanf(pdest,"%c%c%ui",&command,&command,&num_repeats);
  2968.     num_repeats-=1;
  2969.     if (num_repeats < 0)num_repeats=0;
  2970.     num_repeats=(num_repeats & 0x7fff);
  2971.     if(debug)printf("Number of loop repeats changed to %u\n",num_repeats);
  2972. }
  2973.  
  2974. int binexp(int exponent)
  2975. {
  2976.     unsigned int i=0;
  2977.     unsigned int k=2;
  2978.  
  2979.     for(i=0;i<exponent;i++){
  2980.     k=k*2;
  2981.     }
  2982.     return(k);
  2983. }
  2984.  
  2985. /* get memory available in pages */
  2986.  
  2987. unsigned long get_mem_size(void)
  2988. {
  2989.     unsigned int mem_size=0;
  2990.  
  2991.     _asm{
  2992.     mov bx,0ffffh
  2993.     mov ah,048h
  2994.     int 21h
  2995.     jnc mem_error
  2996.     cmp ax,08h
  2997.     jne mem_error
  2998.     mov mem_size,bx
  2999. mem_error:
  3000.     }
  3001.     return((long)mem_size *16);
  3002. }
  3003.  
  3004. /* Print create file error */
  3005.  
  3006. void p_cerror(char *msg,char *name)
  3007. {
  3008.          time_t p_time;
  3009.          time_t c_time;
  3010.  
  3011.          time(&p_time);
  3012.          if(shell)_settextposition(23,1);
  3013.          perror(msg);
  3014.          printf("Couldn't create sound file %s\n",name);
  3015.          time(&c_time);
  3016.          while((c_time-p_time) < 2){
  3017.          time(&c_time);
  3018.          };
  3019. }
  3020.  
  3021. int check_esc(void){
  3022.  
  3023.     int key=0;
  3024.     int scancode=0;
  3025.  
  3026.     if(kbhit()){
  3027.      key=getch();
  3028.     }
  3029.     if(key==27)return(key);
  3030.     else return(0);
  3031. }
  3032.  
  3033.